perm filename HELIB.KKP[S,DOC]4 blob sn#018629 filedate 1973-01-03 generic text, type T, neo UTF8
                          HAND/EYE LIBRARY                        1-1


                      HAND/EYE LIBRARY (HELIB)

                           Karl K. Pingle



                            INTRODUCTION



        This is  an update  of SAILON  35.1.  In  order to  enter the
SAILON into the  computer, some formulae  and all diagrams  have been
taken  out of  the text  and appear  on seperate  pages which  may be
obtained from  me and  inserted into the  listing wherever  you want.
They are keyed to the text. It is basically the same as  the previous
copy except for files DACO, EYECAL, INP, and TSERVO, which  have been
changed  enough to  be  visible to  the user;  files  TARGET, CALCMP,
NUMOUT, FIX, SQUARE, DISKIN, and DSKOUT, which have been deleted; and
files PICRD, TELL, and PICWR, which have been added.





                                NOTICE
                                ______


        This library has been converted for the new SAIL.   It should
still run  with the old  SAIL, except for  changes to  the procedures
mentioned  above.  Tell  me if  any routines  do not  appear  to work
(after you  read the  write up  to be  sure they  are not  working as
______
advertised).  Until the new SAIL  is up on the system  the procedures
documented here  can be  found on  [LIB,HE] and  the library  file is
HELIB.REL[LIB,HE].
                          HAND/EYE LIBRARY                        1-2


                          TABLE OF CONTENTS
                          _____ __ ________

        General Information
        _______ ___________

        2-1     Introduction

        2-3     SAIL Calling Sequences

        2-5     I/O Initialization

        2-6     TV Camera

        2-9     Buffer and Variable Initialization

        2-10    GLOBAL - Global Variables (including status vector)

        Adjusting the TV Camera
        _________ ___ __ ______

        3-1     TSERVO - Pan, Tilt, and Focus Control

        3-7     EYECAL - TV Calibration Routine

        3-8     DACO - Set TV Target Voltage and read AD

        3-11    WHEEL - Color Wheel Manipulator

        Inputting a TV Buffer
        _________ _ __ ______

        4-1     INP - Sets Area to be Read in

        4-2     TVIN - Read a TV Image

        4-4     PICRD - Input a TV Image from the disk

        Randomly Accessing the TV Image
        ________ _________ ___ __ _____

        5-1     ENTER - Buffer access and storing
                        (magnitude and gradient)

        5-4     ENT - Adjust limits of TV input

        Operate on the TV Image
        _______ __ ___ __ _____

        6-1     HISTO - Form a Histogram

        6-2     OPER - Hueckel's  edge Operator

        6-6     AVERAG - Averaging Routine
                          HAND/EYE LIBRARY                        1-3


        6-7     DIFR - Differencing images and processing them

        6-9     DISP - Display a differenced image

        6-10    OP - Hueckel's new edge-line operator

        TV Buffer Output
        __ ______ ______

        7-1     PICWR - Output to the disk

        7-2     PRDUMP - Printer Output of Intensities

        7-3     PORTR - Printer Output with Grey Scale

        7-4     VIDEO - Output to video synthesizer

        General Utility Routines
        _______ _______ ________

        8-1     MISC - Miscellaneous Routines

        8-4     LOOKUP - Symbol Table Searching

        8-5     POT - Pot reading routine

        8-7     GLBGET - Read in global data structure

        8-8     INTERP - Interrupt Package

        8-10    TELL - who has your I/O device

        8-11    SETANG - Angle conversion
                          HAND/EYE LIBRARY                        1-4


                               SYMBOLS
                               _______


        Below is  a list of  all globals, files,  and entries  in the
current library, except  for symbols used internally  between library
routines  only  (they  have  funny names)  and  files  which  have no
references  other than  themselves.  The  reference column  gives the
FILES or table of contents entry where major references to the symbol
may be  found including examples  of its use.  The first  FILE listed
contains the  definition of  the symbol.  By  referring to  the FILES
listed the  user will learn  all he needs  to know about  the symbol,
hopefully.  The type column contains the following codes:

       F     The symbol is the name of a file.

       E     The symbol is an entry point.  If the symbol  appears in
             an EXTERNAL statement in a program, the file  the symbol
             is in will be loaded during a library search of HELIB.

       G     The symbol is a global (or INTERNAL) variable.   It will
             not cause  loading of  a library  file during  a search.
             Variables in  internal procedures  are not  listed.  You
             should not be loading them.

SYMBOL                  TYPE            REFERENCE

ADCHG                   E               MISC
ADJUST                  E               MISC, BUFFER INIT, AVERAG
AVEFOC,AVEPAN,AVETIL    G               TVIN
BCLIP                   E               GLOBAL, TV CAMERA, EYECAL
BITS                    E               GLOBAL, BUFFER INIT
BMAX                    E               GLOBAL,TV CAMERA,BUFFER INIT
BUTTON                  E               MISC
CALLEN                  E               TSERVO
CALPOT, CALSTP, CALSER  E               TSERVO
CONV                    E               TVIN
CWHEEL                  E               WHEEL
DDACO                   E               DACO
DIFER                   E               DIFR
DIFFOC,DIFPAN,DIFTIL    G               TVIN
DISABL                  G               INTERP
DISPLY                  E               DISP
ENTERY,ENTERZ,ENTINT    E               ENT,ENTER,OPER
E1, E2, E3              G               TSERVO
FADCHG                  E               MISC
FLINE                   E               GLOBAL,TV CAMERA,BUFFER INIT
FRDCHG                  E               MISC
GENTER                  E               ENTER
                          HAND/EYE LIBRARY                        1-5


GETPNT                  E               ENTER
GHISTO                  E               HISTO
GIOWD, GLABEL           E               MISC 
GRADNT,GVALUE           E               ENTER
GXCT                    E               MISC
HISTL                   E               HISTO
HISTOG                  E               DIFR
HYSTAB                  E               HISTO 
IND                     G               WHEEL 
INDEX                   G               TVIN
INTINT                  E               INTERP
INTPNT                  E               ENTER
INTWAI                  E               INTERP
IWID                    E               GLOBAL
LENS                    E               TSERVO
LINLEN                  E               GLOBAL
LLINE                   E               GLOBAL,TV CAMERA,BUFFER INIT
LOCKON,LOCKOF           E               MISC
LOOKP                   E               LOOKUP
LSIDE, LSMAX            E               GLOBAL,TV CAMERA,BUFFER INIT
L1, L2, L3              G               TSERVO
MAXDIF                  G               TVIN
NUMBR                   G               AVERAG
NXTLEN                  E               TSERVO
OB, OCL,OD              G               OPER
OPINIT                  E               OPER
ORX,ORY,OSL             G               OPER
PICINI, PICRD           E               PICRD
POTABS, POTREL          E               POT
POTS                    G               POT
PRNT                    E               DIFR
PRPIC                   E               PRDUMP, PORTR
PRTBUF                  G               PORTR
PUTPNT                  E               ENTER
P1, P2, P3              G               TSERVO
RDCHG                   E               MISC
READ                    G               TVIN
RSIDE, RSMAX            E               GLOBAL,TV CAMERA,BUFFER INIT
SLIM                    G               GLOBAL,ENT,OPER
SPWON,SPWOFF            E               MISC
ST                      E               GLOBAL
STATUS                  G               TSERVO
STV                     E               GLOBAL, TVIN, ENTER, OPER
STVFL                   E               GLOBAL, ENTER, OPER
SUMFOC, SUMPAN, SUMTIL  G               TVIN
SUPRES                  E               DIFR
TCLIP                   E               GLOBAL, TV CAMERA, EYECAL
TMAX                    E               GLOBAL,TV CAMERA,BUFFER INIT
                          HAND/EYE LIBRARY                        1-6


TMPBUF                  G               AVERAG
TNOISE                  G               ENTER
TV CONTRL WORDS         G               GLOBAL
TVCAM                   E               GLOBAL, TV CAMERA
TVIN                    FE              TVIN, TV CAMERA
TVOUT                   E               GLOBAL
TVSUBR                  E               TVIN
TVWID                   G               GLOBAL, ENTER, OPER
TVWORD                  E               GLOBAL, BUFFER INIT, TVIN
                          HAND/EYE LIBRARY                        2-1


                             INTRODUCTION
                             ____________


        All subroutines used by the Hand-Eye Project are on a library
file  for  the use  of  people  writing programs  in  this  area.  By
requesting  a  library search  of  the file  when  loading,  only the
subroutines needed by the program will be loaded.

        The library file can be obtained from the author or  found on
the disk  as a system  program.  It can  be searched by  changing the
<altmode> at the end of the loader command string to

                        ,/LSYS:HELIB<altmode>

or if you are using SAIL programs include the line

                    REQUIRE "HELIB[1,3]" LIBRARY;


        The  descriptions of  the  subroutines are  in  the following
format:

     FILE:        Name of the  file containing the subroutine  if not
                  obtained  from the  library file.   It is  also the
                  program name for RAID.

     SIZE:        The  approximate   number  of  words   required  by
                  subroutine in octal.

     ENTRIES:     Internal   references  in   the   subroutine  whose
                  inclusion in an  EXTERNAL statement in  the calling
                  program will cause the program to be  loaded during
                  a  library   search.   If   this  portion   of  the
                  description does not exist for a subroutine then it
                  has one entry which  is the same as the  file name.
                  If it is included,  only the labels listed  with it
                  are entries.

     INTERNAL:    Any labels listed  here are globals defined  in the
                  subroutine which the user may wish to  reference in
                  his program.  They will not cause the program to be
                  loaded during a library search, however.   The user
                  must not  have any INTERNAL  statements referencing
                  any labels listed under ENTRIES or INTERNAL for any
                  subroutine which is loaded.  Unless noted, they are
                  type INTEGER.
                          HAND/EYE LIBRARY                        2-2


     SUBRS:       Lists of all files which this subroutine will cause
                  to  be loaded  during a  library  search, including
                  those called by subroutines it calls.

     ACS:         The contents of  any accumulators listed  here will
                  be changed by the subroutine, or the subroutines it
                  calls.

        The above will be  followed by a detailed discussion  of each
entry. For each entry the following information is given:

CALL:        A sample call in  MACRO and/or SAIL.  If only  the MACRO
             call  is given,  the  subroutine cannot  be  called from
             SAIL, even  if it has  the proper calling  sequence.  If
             only the SAIL call is given, a SAIL calling  sequence is
             used for the MACRO  call.  (See section on  SAIL calls).
             Some   procedures   use  SAIL   library   routines  and,
             therefore,  cannot  be called  unless  the  SAIL runtime
             routines are available  and a SAIL main  program exists.
             The arguments  listed here  will be  referred to  in the
             description.

DECLARATION: If  the subroutine  can be  called by  a SAIL  program a
             sample  declaration  is  given.   Note  especially which
             arguments  are called  by value.   If ANY  appears, then
             those arguments can  be either REAL, INTEGER,  STRING or
             BOOLEAN, to  conform to the  declarations in  the user's
             program.
                          HAND/EYE LIBRARY                        2-3


                        SAIL CALLING SEQUENCES
                        ____ _______ _________


        Most subroutines in the library can be called from  SAIL; new
routines have  only SAIL  calling sequences.  To  call these  from an
assembly  language  program  the following  description  of  the SAIL
calling sequence is given.

      1.   A subroutine FOO is called by PUSHJ 17, FOO.

      2.   All arguments except those declared STRING are pushed onto
           the stack pointed to by AC 17 in the order they  appear in
           the calling sequence.

      3.   Except  for arrays,  variables  called by  VALUE  have the
           contents of the cell put on the stack.  Calls by reference
           put a pointer to the variable on the stack.

      4.   The subroutine must  remove the arguments from  the stack;
           the calling program does not.

      5.   A typed procedure returns a value in accumulator 1. If the
           user does not need the value, he can declare the procedure
           as an untyped one and the value will be discarded.

           EXAMPLE:    If the declaration is

           EXTERNAL  INTEGER   PROCEDURE  FOO(INTEGER   A;  REFERENCE
                       INTEGER  B; INTEGER  C; REFERENCE  INTEGER D);
                       and the call is

                    ZA ← FOO(A,  5,  XX,  -5,  Z);

                       then the  calling sequence generated  by SAIL,
                       and  which  should be  generated  for  a MACRO
                       program is

           PUSH    17,A;               value
           PUSH    17,[[5]];           reference
           PUSH    17,XX;              value
           PUSH    17,[[-5]];          reference
           PUSH    17,[Z];             reference
           PUSHJ   17, FOO;            execute
           MOVEM   1,ZA;               store value

      6.   Arrays are  funny and will  not be described.   Except for
           GIOWD, PICRD, and PICWR, SAIL array identifiers  cannot be
                          HAND/EYE LIBRARY                        2-4


           passed to  subroutines in the  library.  To pass  an array
           FOO, the  argument must  be FOO[A], where  A is  the lower
           limit of the subscript.

      7.   Strings are passed through a special stack in AC  16, with
           the number of characters and a POINT word being given.  To
           pass a string

                     FOO : ASCII  /THIS IS TEXT/

           to subroutine DCHAR, use the following code

           MOVE   16,[IOWD 2, PDL];    2 word stack pointer
           PUSH   16,[=12];            Push count
           PUSH   16,[POINT 7,FOO];    Push pointer
           PUSHJ  17,DCHAR;            Execute

      Warning:

      1.   If you write  a MACRO program which  is to be  called from
           SAIL, you must save AC 16  and 12 on entry (AC 17  also if
           it is not used for a subroutine pushdown stack,  using the
           pointer supplied by  SAIL) and restore them  when exiting.
           They must also be  restored and saved when calling  a SAIL
           procedure from a MACRO program.

      2.   Using SAIL procedures  without a SAIL main  program causes
           problems with initialization  and should not  be attempted
           unless  you are  sure you  know what  you are  doing. SAIL
           procedures  in  the  library  are  so  indicated   at  the
           beginning of their descriptions under SIZE.
                          HAND/EYE LIBRARY                        2-5


                          IO INITIALIZATION
                          __ ______________


1.   Before calling  a library subroutine,  a pushdown  stack pointer
     must be put in AC 17 and must not be destroyed.  When the system
     has been  called during the  execution of a  library subroutine,
     the pointer must be  restored.  SAIL main programs will  do this
     for you.

2.   All TTY I/O in the library, except possibly for SAIL procedures,
     is done using the TTYSER UUO.

3.   Routines using LPT, DTA, DSK, MTA, or TV initialize  and release
     the devices.  The device assignments are:

TV=17   (TVIN)
LPT=16  (PRDUMP, DIFR)
DSK=any (PICRD,PICWR) These routines are given a channel by the user.
                          HAND/EYE LIBRARY                        2-6


                              TV CAMERA
                              __ ______


        While many users of this package will use TV images stored on
the  disk, some  work will  need to  be done  using the  camera.  The
following description of how the camera looks to the  computer should
be sufficient for most users.  The author will be glad to discuss the
camera and any of the subroutines mentioned here in more  detail with
interested users.  WARNING: the TV camera can be  damaged extensively
by improper use and failure to take certain precautions.

        The  computer  can  input a  rectangular  section  of  the TV
picture of  any shape  and size up  to the  entire picture.   For the
purpose of specifying the limits of the rectangle, a  coordinate grid
is placed on the picture,  with the origin in the upper  left corner.
The X and Y axis are both positive with X increasing to the right and
Y increasing down.  The area around the edge of the picture is always
a constant value and, therefore, need not be read.  The  useful range
of coordinates is:

                           octal               decimal
             X             12 - 505            10 - 325
             Y             17 - 372            15 - 250

         The maximum range of coordinates is:

                           octal               decimal
             X             0 - 515             0 - 333
             Y             0 - 400             0 - 256

        In the subroutines  the limits of  the rectangle read  in are
contained in  the following global  variables: (all  global variables
mentioned in this section are in file GLOBAL)


             RSIDE         right side
             LSIDE         left side
             FLINE         first (top) line
             LLINE         last (bottom) line

They must satisfy the following relationships:

             0≤LSIDE ≤ RSIDE ≤ 333(decimal)
             0≤FLINE ≤ LLINE ≤ 256(decimal)


        Otherwise, the action of the TV camera and data  channel will
                          HAND/EYE LIBRARY                        2-7


be rather strange, probably resulting in address checks or hanging up
the TV.  None of  the subroutines discussed below check  to determine
if these relationships hold, except INP.

        Also, the following inequality must hold (decimal):

      (((RSIDE - LSIDE + 1)/9)+ 1) x (LLINE - FLINE + 1) ≤ TVSIZ

where TVSIZ is  the length of the  TV buffer.  The TVIN  package will
truncate the input if this does  not hold and the bottom part  of the
rectangle  will be  lost.  The  routine does  not inform  the calling
program that this happened.

        The edge follower  and various calibration routines  can move
the rectangle to the area  they want to read.  Another set  of global
variables specifies  the outer  limits of  the area  of the  TV image
which can be read.  They are:

             RSMAX         right side
             LSMAX         left side
             TMAX          top
             BMAX          bottom

        The TV image inside the rectangle is read in line by line and
stored in a buffer.  For each  point there is a density value  in the
range 0 - 17, (octal) where 17 is the lightest and 0 is  the darkest.
The density values  are packed nine  to a word.  Each line of  the TV
scan starts in a new word. If the number of points requested per line
is not divisible by 9, the  last word is filled out by  the densities
of points immediately to the right of the area requested.

        The user can select which part of the entire density range of
the camera he wishes to input.  TCLIP and BCLIP contain the upper and
lower  clip levels,  respectively.  They  must satisfy  the following
relationship: (the subroutines do not check this)

                        0 ≤ TCLIP ≤ BCLIP ≤ 7


        When their value is 0 and 7 the entire range of  densities of
the camera is divided into  20 (octal) levels.  As BCLIP  is lowered,
the levels are  shifted toward the light  end of the range,  with the
dark areas becoming  0.  As TCLIP is  raised, the levels  are shifted
toward the  dark end  with the  light areas  becoming 17  (octal).  A
little experimentation on  the computer will  give the user  a better
idea of the effect of these variables.
                          HAND/EYE LIBRARY                        2-8


        There are several TV cameras available.  The proper camera is
selected  by  putting  its  number in  global  cell  TVCAM,  which is
assembled specifying camera one.

        The cameras are:

         0   TV on cart
         1   old COHU TV on electric arm table
         2   new tv on electric arm table
         3   TV in hydraulic arm room
                          HAND/EYE LIBRARY                        2-9


                  BUFFER AND VARIABLE INITIALIZATION
                  ______ ___ ________ ______________


        In the subroutines which require a TV buffer, it is specified
by the variable TVWORD in file GLOBAL.  The user must store in  it an
IOWD giving  the negative  of the length  in the  left half,  and the
starting address  minus one  in the  right half.   If he  has several
buffers they may be  switched as desired, remembering that  the block
of  globals starting  with BCLIP  (in GLOBAL)  and ending  with RSIDE
should contain the  numbers describing the current  buffer.  Whenever
the rectangle  size or BITS  is changed ,  subroutine ADJUST  must be
called.  If a library routine makes the change, it will call ADJUST.

        Other  buffers  are  used  by  AVERAG  and  PORTR  which  are
specified similarly.   Before using the  library, the  description of
file  GLOBAL  should  be  read.   In  the  section  labeled  "TV scan
control", the  variables BCLIP,  TCLIP, FLINE,  RSIDE may  be changed
before calling TVIN.  BITS  may be changed when calling  AVERAG.  The
rest need never be changed by the user.  The library  subroutines can
be used to set  all variables in the  file except TMAX -  RMAX (which
can be left as they are assembled) and TVWORD.
                          HAND/EYE LIBRARY                       2-10


                           GLOBAL VARIABLES
                           ______ _________

FILE:        GLOBAL
SIZE:        25
ENTRIES:     BCLIP, TCLIP, BITS,  IWID, LINLEN, FLINE,  LLINE, LSIDE,
             RSIDE,  TVWORD,  (for internal  use  only:  TVOUT), STV,
             STVFL, ST, BMAX, TMAX, LSMAX, RSMAX, TVCAM, SLIM
ACS:         none

        This  file  contains  global  variables  referred  to  by the
library subroutines.   If the  initial value (below)  is blank  for a
variable, it must be initialized by the user before subroutines using
it are called.

     VARIABLE        INITIAL VALUE   DESCRIPTION

                     (INTERNAL VARIABLES)

     TVOUT           --      TV  buffer  pointer  set  by  subroutine
                             ADJUST

                     (TV SCAN CONTROL - ASSEMBLED IN ORDER GIVEN)

     BCLIP           7       Bottom clip level

     TCLIP           1       Top clip level

     BITS            4       Sample width (set by TVIN)

     IWID            53      Samples per line (set by TVIN)

     LINLEN          0       Words  per  TV  line  (set  by  TVIN and
                             ADJUST)

     FLINE           100     TOP (first) line

     LLINE           200     BOTTOM (last) line

     LSIDE           200     Left side

     RSIDE           300     Right side

                     (BUFFER CONTROL)

     TVWORD                  Specifies TV buffer
                          HAND/EYE LIBRARY                       2-11



                     (TV IMAGE LIMITS - ASSEMBLED IN THIS ORDER)

     TMAX            15      Lower limit of FLINE

     BMAX            372     Upper limit of LLINE

     LSMAX           10      Lower limit of LSIDE

     RSMAX           505     Upper limit of RSIDE

                     (MISC. VARIABLES)

     TVCAM           1       TV camera in use

     TVWID           101     TV Frame width

     STV             0       Nonzero if TV input converted  from grey
                             code (see ENTER).

     STVFL           0       Nonzero if TV buffer full(see ENTER).

     ST              0       Nonzero  if  disk  input  instead  of TV
                             (used by edge follower)

     SLIM            0       Nonzero  if flexable  limits on  tv scan
                             (see ENT).
                          HAND/EYE LIBRARY                        3-1


              TSERVO - SERVO ROUTINE FOR PAN,TILT, FOCUS
              ______ _ _____ _______ ___ _________ _____

FILE:        TSERVO
SIZE:        321
ENTRY:       TSERVO, CALPOT, CALSTP, CALLEN, NXTLEN, CALSER
INTERNAL:    STATUS, LENS, P1, P2, P3, L1, L2, L3, E1, E2, E3
ACS:         1

        The TV used  by the hand-eye programs  has four motors  on it
which are under computer control;  one to pan the TV left  and right,
one to tilt it up and down,  one to move the vidicon tube in  and out
to provide focusing, and one to move the turret to select one  of the
four  lenses mounted  on it.   The pan,  tilt, and  focus  motors are
connected to potentiometers which allow the computer to determine the
position  of the  motors.  The  turret motor  turns the  turret  in a
counterclockwise  motion as  you face  the camera.   If the  motor is
stopped after the turret starts to move, it will continue to the next
position.


                              POT LIMITS


        This routine will move the pan, tilt, and focus motors to any
desired position as well as change lenses.  The user, in his program,
starts the servo program, which  runs in spacewar mode, and  gives it
the pot readings of  the desired position.  It  is up to the  user to
make sure that the readings given can be reached by the  motors.  The
maximum and minimum values are (in decimal)

     focus  far         2048
            near        0

     tilt   up          2000
            down        -1884

     pan    right       2048 (in direction camera is facing)
            left        -2000

        The  limits  for  the  tilt  and  focus  motors  are  set  by
mechanical stops.  The pan motor, however, can turn 350  degrees and,
if allowed  to servo to  a reading outside  of the given  stops, will
damage the cables to it. (This routine does not check limits)


                            SERVO CONTROL
                          HAND/EYE LIBRARY                        3-2


        Communication  with  the  servo  routine  is  accomplished by
altering bits in a status  word in the servo routine.   Various other
words in the routine may be of interest to the user.  They  are given
below:

      STATUS Holds status  bits for  communication betweeen  user and
             servo routine.

      LENS   For lens changing.

      P1     Latest focus pot reading

      P2     Latest tilt pot reading.

      P3     Latest pan pot reading.

      L1     Final focus pot reading.

      L2     Final tilt pot reading.

      L3     Final pan pot reading.

      E1     Focus tolerance (assembled as 4)

      E2     Tilt tolerance (assembled as 10)

      E3     Pan tolerance (assembled as 10)

        The last three cells determine how close Pi must be to  Li to
stop servoing.  They may be increased, but should not be decreased as
this will greatly shorten the life of the relays in the controller.

        The  bits in  STATUS which  are used  by the  routine  are as
follows:

BIT      NAME  USE
___      ____  ___

               GENERAL BITS

1        DONE  Set by TSERVO when all actions have been  completed or
               an error condition has been detected.  While it is on,
               the routine idles  clearing the time  counters, making
               sure  all motors  are off,  and setting  the  RUN bit.
               This bit is  never cleared by  the routine.  If  it is
               not set all error bits will be cleared each tick.

2        RUN   Set  each  tick by  TSERVO.   It is  never  cleared or
               tested.
                          HAND/EYE LIBRARY                        3-3


         REQUEST BITS

4        READ  (POT READ REQUEST) If this bit is on, the  current pot
               readings are read and stored in P1, P2, and P3.  If no
               other request  bits are  on the DONE  bit will  be set
               immediately.   This bit  is never  cleared and  it can
               cause bits MISS, ADH, GHANG to be set.

10       SERVO (SERVO REQUEST) If this bit is set the pan,  tilt, and
               focus motors are  servoed until they are  within E1-E3
               of L1-L3.   The last  pot readings  will be  in P1-P3.
               When  all  motors  are  finished,  this  bit  will  be
               cleared,  unless an  error occurs  first.  If  READ is
               set,  it will  be ignored.   This bit  can  cause bits
               MISS, ADH, FHANG, THANG, PHANG, GHAND to be set.

20       LENS  (LENS CHANGE REQUEST) If  this bit is set,  the turret
               is moved to the lens specified by the low  order three
               bits of LENS.  If this lens is in position,  no motion
               will occur.  If LENS<0, the next lens in sequence will
               be moved into position  and its number put  into LENS.
               If an  error occurs,  the turret may  or may  not have
               moved; it will not stop between lenses.  In  this case
               the requested lens may not be in position and LENS may
               not contain the correct lens number.  This bit will be
               cleared  when the  proper lens  is in  position  if an
               error has  not occured.   If both  LENS and  LREAD are
               set, LREAD is ignored.  This bit can cause  bits LHAND
               and GHANG to be set.

40       LREAD (LENS READ  REQUEST) If this  bit is set,  the current
               lens number  is put into  LENS.  If only  LREAD and/or
               READ are  set, the DONE  bit will be  set immediately.
               This bit is never  cleared and can cause bit  GHANG to
               be set.

         ERROR  BITS  (DONE  bit always  set,  counters  cleared, and
               motors turned ofF)

100      MISS  136  data  channel  has  missed  data  for  25 (octal)
               consecutive reads.  This is either a hardware error or
               somebody else is using the A-D converter.

200      ADH   The A-D converter is  hung. Same problems as  for MISS
               or PDP-6 is not running.

         (The  rest of  the errors  are controlled  by  time counters
               which are cleared whenever the DONE bit is set)
                          HAND/EYE LIBRARY                        3-4


400      LHANG Lens  change  did  not  terminate  withing  4 seconds.
               (Hardware problem)

1000     FHANG The focus motor was not moving for 1 second and is not
               at  its final  position;  assumed hung.   This  can be
               caused  by  a  hardware problem  (what  can't  !!), by
               hitting a stop, or because the controls are in manual.
               The  not  moving  tests  are  controled  by  the error
               tolerences E1-E3.

2000     THANG Tilt motor hung. See FHANG.

4000     PHANG Pan motor hung.  See FHANG.

10000    GHANG TSERVO did not set the DONE bit withing 20  seconds of
               the  time it  was  started or  the DONE  bit  was last
               cleared.  This is  either a hardware  problem, program
               bug, core garbaging, or someone else is using  the A-D
               (see below)

         CONDITION BITS

100000   CONFL This bit is set if  TSERVO had to skip a  tick because
               someone  else was  using the  A-D.  Lens  changing and
               reading pots  or the  lens are  not affected.   If the
               other user hangs on to the A-D, the GHANG flag  may be
               set.

        When the  user's program  wants to servo,  it sets  STATUS as
desired and executes

        SPCWAR          0,636367        (in assembly languages)
        SPCWAR          1,TSERVO

or

        SPWON(1,TSERVO)                 (in SAIL - see file MISC)

to start spacewar mode.  The opcode SPCWAR is [43B8].  When  the DONE
bit is  set all actions  are completed.  The  routine will  then idle
until the DONE bit is cleared again or spacewar mode is turned off.

        When finished with the servo routine, make sure the  DONE bit
has been set by the servo routine and then execute SPCWAR 0,636367 to
turn it off (SPWOFF to SAIL).

        It  is  very  important  to note  that  once  the  motors are
                          HAND/EYE LIBRARY                        3-5


started, calling the system or  killing your job will not  stop them.
They can be  stopped temporarily by  putting the controls  in manual,
which  will cause  them to  be  turned off  if the  servo  routine is
running.   Otherwise  they will  start  again when  the  controls are
switched back to  computer control.  The only  way the motors  can be
stopped when the  servo routine is not  running is by  executing CONO
700,40, in spacewar mode  or by executing procedure  CALSTP mentioned
below.

        It  should also  be  noted that  the action  of  the routine,
especially the lens change,  may change as the timesharing  system is
changed.  An attempt  will be made to  keep it updated to  the newest
system in use.

        The  following routines  allow the  user to  do a  few useful
things without having to mess with spacewar mode directly.


CALL:        CALSER;                                 (SAIL)
             PUSHJ 17,CALSER(MACRO)

DECLARATION: EXTERNAL PROCEDURE CALSER;

        The first time it is called after the program is  loaded, the
current pot readings  are stored in L1,  L2, and L3.   Thereafter, if
the  TV is  under computer  control, it  will be  servoed to  the set
readings.  If  the TV  is in  manual, the  current pot  readings will
again be saved.  The error bits will not be checked.


CALL:        CALSTP;                                 (SAIL)
             PUSHJ 17,CALSTP;                        (MACRO)

DECLARATION: EXTERNAL PROCEDURE CALSTP;

        CALSTP  makes sure  all motors  are off.   It also  turns off
spacewar mode.


CALL:        CALLEN;                                 (SAIL)
             PUSHJ 17.CALLEN;                        (MACRO)

DECLARATION: EXTERNAL PROCEDURE CALLEN;

        CALLEN reads  the position of  the turret without  moving it,
and stores the lens number in LENS.
                          HAND/EYE LIBRARY                        3-6




CALL:        NXTLEN;                                 (SAIL)
             PUSHJ 17,NXTLEN                         (MACRO)

DECLARATION: EXTERNAL PROCEDURE NXTLEN;

        NXTLEN moves the turret to the next lens position  and leaves
the lens number in LENS.  Error bits are not checked.


CALL:        CALPOT;                                 (SAIL)
             PUSHJ 17,CALPOT                         (MACRO)

DECLARATION: EXTERNAL PROCEDURE CALPOT;

        CALPOT puts the current pot readings in P1, P2, and P3.
                          HAND/EYE LIBRARY                        3-7


                        EYECAL -TV CALIBRATION
                        ______ ___ ___________

FILE:        EYECAL
SIZE:        276
CALLS:       GLOBAL, ENTER, TVIN, QUAM DISPLAY ROUTINES, SAIL RUNTIME
             ROUTINES ,POT,TELL
ACS:         ALL


CALL:        EYECAL(BUF_SIZ,FRAME,FLAG,BUFFER);      (SAIL)

DECLARATION: EXTERNAL PROCEDURE EYECAL(INTEGER BUF_SIZ,FRAME,FLAG;
                 INTEGER ARRAY BUFR);

        BUFR is a display buffer for the QUAM display routines, which
must be loaded.  BUF_SIZ is the size of the buffer, and FRAME  is the
piece-of-glass number  the routines are  to use.  The  routine starts
with the verify operation if FLAG is FALSE, or manual if it  is TRUE,
and will accept the letters V, M or Y (no carriage return  needed) at
any time to  switch to another  operation.  All other  characters are
ignored.

        The operations are:

      Y    finished - Return to the calling program.

      M    manual - Continuously  scan one line  of the TV  image and
           display a position vs. intensity graph on the  CRT.  TCLIP
           and BCLIP are set  to 7 initially.  Arrows on  the display
           indicate  the  position of  intensities  0 and  17  in the
           graph.  Pot 12 moves the  scan line up and down.   Pots 14
           and 15  alter BCLIP  and TCLIP,  whose current  values are
           displayed.  The program will not allow their values  to go
           outside the permissible limits or for BCLIP to become less
           than TCLIP. The pots are read in absolute mode.

      V    verify - Same as  manual only the currently  stored values
           of TCLIP and BCLIP are used to start.

        This subroutine  requires a  TV buffer  at least  140 (octal)
words long and a display buffer at least 350 (decimal) words long. It
scans the TV image, using  TMAX, BMAX, RSMAX and LSMAX as  the limits
of the image.  When it exits, LLINE, FLINE, RSIDE, and LSIDE  are set
to the limits of the last  line read from the TV. If the  pot routine
cannot initialize the AD, a message will be typed.

        WARNING If  called from an  assembly language routine,  AC 16
        _______
must have a pointer to the SAIL string pushdown list.
                          HAND/EYE LIBRARY                        3-8


                     DACO - SET TV TARGET VOLTAGE
                     ____ _ ___ __ ______ _______

FILE:        DACO
SIZE:        273
ENTRY:       DDACO
SUBRS:       TELL
EXTERNAL:    AUTO_ACC, DAC_ACC
ACS:         0-6


CALL:        VAL←DDACO(DACR);                        (SAIL)

             PUSH 17,DACR
             PUSHJ 17,DDACO                          (FAIL)
             MOVEM 1,VAL

DECLARATION:EXTERNAL INTEGER PROCEDURE DDACO(INTEGER DACR);

        The  target voltage  of the  COHU TV  camera can  be changed,
under program control, to  vary the camera's sensitivity.   A digital
to analog converter (DAC) can be set to numbers in the range  0-63 to
adjust the target voltage, where  0 is the most sensitive and  63 the
least (actually  62 is the  highest number which  should be  used; on
some days of the week 63 causes a negative target voltage).   The DAC
is only effective if the TV sensitivity control, on the box under the
hand/eye  table, is  in auto  mode.  In  this mode,  the  TV hardware
generates a voltage based on the average brightness of the scene (the
auto target voltage or ATV) which will normally be the target voltage
used  by the  TV.  To  protect the  vidicon, the  DAC cannot  set the
target  voltage higher  than  the ATV  (which  is set  by  a hardware
adjustment made only by experts).  The target voltage is connected to
an analog to digital converter (AD) which allows programs to read it.
Thus, if the DAC is set  to 62 and then decremented toward 0,  the AD
readings  will decrease  until  the ATV  is reached  and  then remain
approximately constant  as the  DAC is  decremented further.   Due to
noise  problems, settling  times,  and instability  in  the hardware,
accurate AD readings are hard to obtain and the  relationship between
the DAC settings and AD readings varies from run to run.

        To solve all (?) of your problems with this kludge, DDACO was
created.  If DACR≥0 the  low order six bits  will be used to  set the
DAC.  If DACR<0 the DAC will not be changed.  Once set, the  DAC will
stay set until  changed by a program  or cleared by a  hardware reset
when the system is started.

        The  current  AD reading  is  returned as  the  value  of the
procedure. It will be in the range 0-4096.  If DACR<0, the reading is
                          HAND/EYE LIBRARY                        3-9


returned in  one tick  (1/60th of a  second).  If  the DAC  was being
changed  also,  the  procedure waits  until  the  target  voltage has
stabilized to within a tolerance, which will take from 40  ticks (2/3
sec.) to  over 130 ticks  (2 1/6 sec.).   The time and  tolerance are
functions of the direction of the change, the size of the change, and
the nearness  of the new  DAC setting to  the ATV.  The  tolerance is
much higher when the DAC is  near the ATV, due to oscillation  in the
ATV.  If the DAC setting is changed from below to above the  ATV, the
settling time will be near the upper limit; it will be near the lower
limit otherwise.  DDACO runs in spacewar mode.

DDACO ERRORS
_____ ______

        There  are three  error messages  from DDACO,  each  of which
gives you  the option  of trying again  or continuing.   The messages
are:

      DATA MISSED ON 25 CONSECUTIVE TRIES - AD ---- The AD  is unable
           to read  the target  voltage.  This  is either  a hardware
           error or another program is using the AD at the  same time
           (DDACO does not INIT is AD before using it).  Try again or
           find  a  technician.  Continuing  will  give  an incorrect
           reading.

      HUNG DEVICE AD ---- The A-D will not run.  See above error.

      DACO  TIMED  OUT  ----  DDACO  ran  4  seconds  without  the AD
           settling.  Retrying will give a good reading  (hopefully -
           it will not give the error message again).  Continuing may
           give a good reading.

USING DDACO
_____ _____

        This procedure must know the current DAC setting and ATV when
entered  to  function  properly.   These  are  contained  in integers
DAC_ACC and AUTO_ACC (see below)  which must be provided by  the user
if the  global model (PREAMB.SAI[II,HE])  is not in  use and  must be
initialized by the  user (see below).   Always use this  procedure to
change the DAC so it can update these variables.

INITIALIZING THE ATV
____________ ___ ___

        A procedure exists which will initialize DDACO by finding the
ATV and  setting the DAC  to it.   It is called  SENSINIT and  can be
obtained from me.  It takes  no arguments and uses all of  the global
variables  listed  below, provided  by  PREAMB.SAI or  the  user. The
proper way to call SENSINIT at the start of each run is
                          HAND/EYE LIBRARY                       3-10


              IF ¬SENSCAL_ACC∨CHANGE_ACC THEN SENSINIT;


        After the first call, additional calls of SENSINIT will check
the ATV and change AUTO_ACC if necessary.

GLOBAL VARIABLES
______ _________

        The following  variables in the  global model should  be kept
updated by programs using  the hand/eye system.  Those needed  by the
above procedures must  be provided by the  user in an outer  block if
the global model is not available.

     AUTO_ACC      DAC setting which corresponds so the ATV.   Set by
                   SENSINIT and used by DDACO.

     AUTOCAL_ACC   TRUE if  array TABLE_ACC  has been  initialized by
                   SENSINIT, which sets and uses it.

     DAC_ACC       the  current  DAC setting.   Set  by  SENSINIT and
                   DDACO and used by both.

     CHANGE_ACC    TRUE if the  scene has changed (i.e.  objects have
                   been  moved,  the color  filters  changed,  or the
                   lights  changed).  Used  and cleared  by SENSINIT.
                   Must be set by user.

     TABLE_ACC     an  array  [0:63]  indexed  by  DAC  settings.  It
                   contains AD  readings for  all DAC  settings which
                   have been used; -1 for other settings.  Values are
                   valid only for indicies ≥AUTO_ACC.

     SENSCAL_ACC   TRUE if SENSINIT has been called.

        Note that  if you  are running with  a shared  global segment
other jobs may  be using and  changing these values.   The procedures
are aware of this and will do the right thing if you do not mess with
the variables or change the DAC with other routines.

INTERACTION WITH OTHER USERS

        This program reads the  A-D in spacewar mode  without INITing
it. The procedure  will get it even  if other users have  assigned or
INITed it.  If  another user has the  A-D when this program  wants to
read it, DDACO will wait.  If  the other user keeps it too  long, you
will  get the  "DACO  TIMED OUT"  error  message and,  in  addtion, a
message will be typed out telling  you the job number and PPN  of the
job which has the AD inited so you can yell at them.
                          HAND/EYE LIBRARY                       3-11


                   WHEEL - COLOR WHEEL MANIPULATOR
                   _____ _ _____ _____ ___________

FILE:        WHEEL
SIZE:        170
ENTRY:       CWHEEL
INTERNAL:    IND
ACS:         0-4


CALL:        TEST←CWHEEL(CODE);                      (SAIL)

             PUSH 17,CODE
             PUSHJ 17,CWHEEL                         (FAIL)
             MOVEM 1,TEST

DECLARATION: EXTERNAL BOOLEAN PROCEDURE CWHEEL(INTEGER CODE);

        This routine changes and interrogates the color wheel  on the
TV  camera.  On  exit,  IND contains  a number  0-3  specifying which
filter is in position according to the codes below.  CODE  is decoded
as follows:

    0    position red filter

    1    position blue filter

    2    position green filter

    3    position clear filter

    4    automatic - the first time called you get the  clear filter.
         Successive calls (without calls using codes 0-3  in between)
         get you blue ,red, and green, in that order.  The cycle will
         repeat indefinitely.

    5    Same as 4  except you never get  the clear filter.  4  and 5
         can be intermixed but the clear filter will be  skipped only
         if 5 is used when it was next up.

    6    Put  the filter  number (0-3)  which is  in position  in IND
         without  changing filters.   The  other codes  also  set IND
         automatically.

        If  the color  wheel  cannot be  moved to  the  proper filter
(power is off or a mechanical problem) a message is typed and you are
given a chance to retry it, or continue.  The procedure  returns TRUE
if the requested  action was successfully  carried out; FALSE  if you
continued from the error message.
                          HAND/EYE LIBRARY                        4-1


                  INP - VARIABLE TV INPUT SUBROUTINE
                  ___ _ ________ __ _____ __________

FILE:        INP
SIZE:        145
SUBRS        TVIN, MISC, GLOBAL, POT, TELL
ACS:         ALL


CALL:        INP;(SAIL)

DECLARATION: EXTERNAL PROCEDURE INP;

        This  subroutine allows  the user  to position  the  TV input
using the  pots.  The  TV camera  is read  continuously and  the pots
checked as follows:

      POT  Action
      ___  ______
      12   Move left and right sides together
      13   Move top and bottom sides together
      14   Move top side
      15   Move right side

        Note HINT FOR POT USERS under file POT.

        Thus 12 and 13 move the rectangle while 14 and 15  change its
size.  If the  result of  the change  would be  to move  part  of the
rectangle outside the TV input area, to make opposite sides cross, or
to make the rectangle so large that it would overflow the  TV buffer,
the rectangle  is adjusted to  be legal but  as close as  possible to
your request.  If the area is too large, lines are dropped off of the
bottom of the image.  Typing any character on the TTY will  cause INP
to return.  This routine sets FLINE, LLINE, etc. to the limits of the
rectangle. If this is used to set the image limits for routines which
use TMAX, BMAX, etc. (such as EYECAL and ENTER), they must be  set by
copying from FLINE, etc.

        If  the AD  cannot  be initialized  for reading  the  pots, a
message will be typed.
                          HAND/EYE LIBRARY                        4-2


                      TVIN - TV INPUT SUBROUTINE
                      ____ _ __ _____ __________

FILE:        TVIN
SIZE:        564
ENTRIES:     TVIN, TVSUBR, CONV
SUBRS:       MISC,GLOBAL
INTERNAL:    MAXDIF, AVEFOC, AVEPAN, AVETIL, DIFFOC,  DIFPAN, DIFTIL,
             READ, INDEX, SUMFOC, SUMPAN, SUMTIL
ACS:         NONE


CALL:        TVSUBR                                  (SAIL)

DECLARATION: EXTERNAL PROCEDURE TVSUBR;

        TVSUBR initializes  the TV camera  and starts reading  one TV
image in grey code into a buffer as specified by the TV control words
and TVWORD.  The  rectangle read is  bounded by LSIDE,  RSIDE, FLINE,
and LLINE.   The clip levels  are set according  to TCLIP  and BCLIP.
BITS is set to 4 by the subroutine. If the number of  words necessary
to hold  the entire image  is greater than  specified by  TVWORD, the
bottom  of the  image is  lost.   The area  read appears  as  a white
rectangle on the monitor.

        The size of the image read in is the minimum of the length of
the TV buffer and the size computed from the rectangle limits.

        If  the program  hangs  up when  trying to  read  the camera,
either the data  channel is turned off,  or the channel  is disabled.
If the restrictions  on the clip levels  and limits of  the rectangle
mentioned in the section on  the TV camera are violated, one  or more
of the following will occur: the system will respond with  an ADDRESS
CHECK error message, incorrect information will be put in the buffer,
the wrong section of the TV image will be read, or attempts to output
the contents of the TV buffer will wipe out the program.  CANNOT INIT
TV is typed if the subroutine has failed 1000 times to initialize the
TV camera. Someone else is using it.  Typing any character  causes it
to try another 1000 times.

        If the TV image has been read in successfully, the  TV camera
will be released before the program returns.

        There are  four error  messages associated  with the  TV.  TV
DATA MISSED-TVIN is typed when the data channel has missed data on 50
consecutive attempts to read  the camera.  The program will  then try
another 50 times.   PARITY ERROR is typed  when 10 parity  errors are
counted  without  a  successful  read.   This  indicates  a  hardward
                          HAND/EYE LIBRARY                        4-3


malfunction.  SYS ERR -TVIN is  typed when the NON-EX MEM flag  is on
in the data channel and usually means the time sharing system is sick
and may die. This condition may also occur if the data channel enable
switch is switched on after  the channel has hung trying to  read the
camera.   TV  IS HUNG-TVIN  is  typed  if the  system  thinks  the TV
interface is hung.  The  program returns to the monitor  after either
of  the last  three  messages and  the  program must  start  from the
beginning.

        For normal reading, internal  integer READ is zero, as  it is
assembled.  If  it is  set to a  positive value,  the pan,  tilt, and
focus pots on the TV will be read continuously in spacewar mode while
the TV is  being read and,  when the TV  is finished, if  the maximum
difference in pot  readings, indicating the  amount of jiggle  in the
TV, is greater  than READ, the image  is rejected as missed  data and
the TV is read again.  On exit, if READ was ≠ 0, INDEX is  the number
of times the pots were read, MAXDIF is the maximum difference  in pot
readings.  Also, AVEFOC, AVEPAN, and AVETIL are the  average readings
for the pots and DIFFOC,  DIFPAN, and DIFTIL are the  differences for
each.   SUMFOR, SUMPAN,  and  SUMTIL are  the sums  of  the readings.
Several more error messages can  result wen this option is  used.  AD
DATA  MISSED-TVIN means  the A-D  converter was  continuously missing
data for 10 reads.  POTS  TOO NOISY-TVIN means the pot  readings were
fluctuating too much.  For these last two messages, the  program will
keep trying  until it wins  or you  stop it.  If  the user  wants his
program to control pot fluctuation, set READ to a large number  so it
will always  return, and test  the value of  MAXDIF yourself.   AD IS
HUNG-TVIN means the 136 or A-D is hung and will cause the  program to
halt.  Three other messages, SPCWAR JOB HUNG, MAIN JOB HUNG ON ENTRY,
and MAIN JOB HUNG ON EXIT  result for bugs or timing errors.   See me
if they occur.


CALL:        CONV;                                   (SAIL)

DECLARATION: EXTERNAL PROCEDURE CONV;

        CONV converts the contents of the TV buffer from grey code to
binary if STV is cleared, and sets STV; otherwise it does nothing.


CALL:        TVIN;                                   (SAIL)

DECLARATION: EXTERNAL PROCEDURE TVIN;

        TVIN calls TVSUBR followed by CONV.
                          HAND/EYE LIBRARY                        4-4


                   PICRD - INPUT FROM DISK STORAGE
                   _____ _ _____ ____ ____ _______

FILE:        PICRD
ENTRIES:     PICINI, PICRD, PICDES, PICLIN
SIZE:        377
SUBRS:       MISC, GLOBAL, SAIL runtime routines
ACS:         ALL

                             FILE FORMAT


        The new disk picture I/O routines use a new and more flexible
format for  picture files.   Each file is  considered to  contain one
picture, which may  have been taken  through several filters,  or two
cameras (stero), or have been operated on, with the results stored in
the file.  In the  file is header information describing  the picture
size (BITS, LINLEN, FLINE, LLINE, LSIDE, and RSIDE) and  data blocks.
A data block is  a collection of data  which is processed by  the I/O
routines as a single entity. I.E., it must be read in or  written out
all at once; one cannot read  in portions of a data block.   The user
can specify  anything he wants  as data blocks  for output,  but many
data blocks have been reserved for specific things and are recognized
as  such by  programs  using the  picture files.   The  standard data
blocks are the picture through each of the four filters  (and through
two cameras if a stereo  picture), the camera transform, and  a title
and description.   Each disk file  may contain as  few or as  many of
these data blocks as desired.  The input routine will tell the caller
which data blocks are contained  in the file and allow him  to select
the ones he  wants.  The first part  of the file contains  the header
variables  described   above  and   data  block   descriptors.   Each
descriptor specifies where in the file the data block starts  and how
long it is.  The contents of the reserved data blocks  are determined
by  the  order  of  their  descriptors  in  the  file.   Below  is  a
description of the file format, of interest mainly to people who want
to write their own I/O routines.

    WORD   DECRIPTION
    ____   __________
    0      -1  if new  format file  (a real  -1, not  just negative);
           anything else for old format files
    1      BITS (see  TV control  word section of  file GLOBAL  for a
           description of these words)
    2      LINLEN
    3      FLINE
    4      LLINE
    5      LSIDE
    6      RSIDE
    7      XWD  -WC,<LEFT CLEAR  PICTURE> (A  word specifying  a data
                          HAND/EYE LIBRARY                        4-5


           block.  Note that it is not an IOWD; the left half  is the
           negative of the  word count and  the right half  points to
           the location  in the file  of the first  word of  the data
           block.   This word  is  zero if  the data  block  does not
           exist.  See the description of the storage array below for
           the description of these data blocks)
    10     XWD -WC,<LEFT RED PICTURE>
    11     XWD -WC,<LEFT BLUE PICTURE>
    12     XWD -WC,<LEFT GREEN PICTURE>
    13     XWD -WC,<PICTURE TITLE>
    14     XWD -WC,<PICTURE DESCRIPTION>
    15     XWD -WC,<LEFT CAMERA TRANSFORM>
    16     XWD -WC,<LEFT CLEAR CODE TABLE>
    17     XWD -WC,<RIGHT CLEAR PICTURE>
    20     XWD -WC,<RIGHT RED PICTURE>
    21     XWD -WC,<RIGHT BLUE PICTURE>
    22     XWD -WC,<RIGHT GREEN PICTURE>
    23     XWD -WC,<RIGHT CAMERA TRANSFORM>
    24     XWD -WC,<RIGHT CLEAR CODE TABLE>
    25     XWD -XC,<STERO REGISTRATION TABLE>
    26-37  reserved  for other  data block  descriptors which  may be
           added in the  future.  Users may  use this space  for data
           blocks of their  own but it is  subject to use  by library
           programs in the future.  If you have a continuing  use for
           other  data  blocks  see  me  about  adding  them  to  the
           permanent list.
    40-177 reserved  for  user  specified  information  of  any kind.
           These  words  are  not  read  or  written  by  the library
           routines; you have to  have your own disk I/O  routines to
           access them.
    200    beginning of the data blocks

                       DATA BLOCK SPECIFICATION


        The input  and output  routines require as  a parameter  a 25
word integer array which is used to pass information between the user
and the I/O  routines concerning which  data blocks are  available or
desired.  The file format contains room for 25 data blocks.   This is
infinitely  extendable  as  one  of  the  data  blocks  could  be  an
arbitrarily  long array  of descriptors  for more  data  blocks.  The
first fifteen  words of  the 25  word array  are reserved  for system
defined data  blocks.  The  last ten are  available for  user defined
data blocks.  The data block  associated with each word of  the array
is given below:
                          HAND/EYE LIBRARY                        4-6


ARRAY  DATA BLOCK
_____  ____ _____
1      the TV  image through the  clear filter. If  this is  a stereo
       picture  this is  the left  image. If  this is  an  old format
       picture, this is the only data block which is available.
2      the left or only TV image through the red filter
3      the left or only TV image through the blue filter
4      the left or only TV image through the green filter
5      the  picture's  title.   It  is  a  short  string  for titling
       displays,  listings,  etc.    The  string  is  in   ASCII  and
       terminates with a zero character.  It is not, however, in SAIL
       string space.  It must  be copied for use with  SAIL programs,
       using  CVSTR and  CVASC.  On  generating this  data  block for
       output, be sure there is a zero character, or word, at the end
       of  the string.   The count  in the  data block  descriptor is
       words, not characters.  Procedures for processing this and the
       next data block are given later.
6      a description  of the  picture, which  can be  as long  as the
       producer of  the picture  desires.  It  should tell  about the
       picture and associated processing which has been  performed on
       it.  Again, it should end with a zero character.  See comments
       for title, above.
7      the  camera  transform for  the  left or  only  image.   It is
       currently a 8x3 real array containing:
            1:3,1:3    colineation matrix (TV←table)
            4,1:3      lens center in table coordinates
            5,1:2      TV coordinates of point on image plane pierced
                       by the lens axis
            5,3        1
            6:8,1:3    inverse colineation matrix (table←TV)
            7,1:3      pot readings for pan, tilt, focus (camera #1)
            8,1        camera number
            8,2        lens number (camera #1)
            8,3        0
8      code table for left clear image (for compressing data)
9      the right TV image through the clear filter (exists only  if a
       stereo picture)
10     the right TV image  through the red filter for  stereo picture
       only
11     the right TV image through the blue filter for  stereo picture
       only
12     the right TV image through the green filter for stereo picture
       only
13     the  camera transform  for  the right  image  (stereo pictures
       only)
14     right clear code table for stereo pictures only
15     registration table for  stereo pictures (format  unknown since
       stereo pictures do not exist yet)
16-25  reserved for expansion or user defined data blocks
                          HAND/EYE LIBRARY                        4-7


                 INITIALIZING THE PICTURE FILE INPUT



CALL:        NEW←PICINI(CHAN,FILE,EXT,PPN,FAIL,STORAGE);   (SAIL)

DECLARATION: EXTERNAL BOOLEAN PROCEDURE PICINI(INTEGER CHAN,FILE,EXT,
                 PPN; REFERENCE BOOLEAN FAIL; INTEGER ARRAY STORAGE);

        This procedure opens  the disk file FILE.EXT[PPN]  on channel
CHAN.  The  parts of  the file  name are  given to  it in  SIXBIT, as
produced by the SAIL procedure  CVFIL.  If the file cannot  be found,
there is no free core, or there are read errors, FAIL is TRUE on exit
and there is no data.  STORAGE is the 25 (decimal) word array of data
block information.  The procedure clears the array and then fills the
proper entries with the lengths,  in words, of each data  block which
exists in this file.  Unless you are reading a stereo  picture, words
9-25 will always be zero.  If it is an old format picture,  only word
one will be non-zero. If it is a new format black and  white picture,
at most words 1, 5, 6,  7, and 8 will be non-zero. PICINI  also reads
in  the  header  words  described  earlier  and  stores  then  in the
appropriate variables. The value of the procedure is TRUE if it found
a new format file.

                     INPUT OF ENTIRE DATA BLOCKS



CALL:        PICRD(FAIL,STORAGE);                    (SAIL)

DECLARATION: EXTERNAL PROCEDURE PICRD(REFERENCE BOOLEAN FAIL;
                 INTEGER ARRAY STORAGE);

        After calling  PICINI, allocate core  for the  available data
that you want  and put the  address of the  first word of  each block
allocated in the proper entry of STORAGE.  Clear the entries  for any
data blocks which  are available but which  you do not want.   If you
got the core with GETCOR, the IOWD returned plus one can be used (the
left half is ignored).   If you created a SAIL  array, GIOWD(array)+1
or  GLABEL(array[1]) will  produce the  correct entry.   For example,
given a non-zero entry in STORAGE[1] upon return from PICINI,  all of
the below are equivalent to specify where you want the  image through
the clear filter stored:

        STORAGE[1] ← GETCOR(STORAGE[1])+1;
or
        BEGIN INTEGER ARRAY BUF[1:STORAGE[1]];
        STORAGE[1] ← GIOWD(BUF)+1;
                          HAND/EYE LIBRARY                        4-8


or
        BEGIN INTEGER ARRAY BUF[1:STORAGE[1]];
        STORAGE[1] ← GLABEL(BUF[1]);

GIOWD, GETCOR, GLABEL are described elsewhere in the document.


        Each time it  is called, PICRD will  fill the blocks  of core
you gave  it with the  data blocks in  the file.  Data  is transfered
only for data blocks where the entry in STORAGE was non-zero  both on
exit for PICINI and on entry to PICRD.  The procedure does  not check
                                                            ___
your blocks of core to be sure they are big enough.  FAIL is  TRUE on
exit if it was  TRUE on entry (an error  in PICINI) or if  there were
read  errors.   In this  case,  the data  blocks  may or  may  not be
present.

        PICRD may be called  as many times as desired.   For example,
if you  are processing  the image through  each filter  serially, one
array can be created and  its address put in STORAGE[1].   PICRD will
then fill  it with  the picture through  the clear  filter.  Clearing
STORAGE[1] and putting the  array address in STORAGE[2] will  get you
the picture through  the red filter in  the same array the  next time
PICRD is  called.  The same  data block can  also be read  in several
times if desired.  PICRD will not release the channel you gave PICINI
to open the file.  When you  are done with the file it  is considered
good form to release it yourself.

                      INPUT OF FILE DESCRIPTION



CALL:        PICDES(FAIL,STORAGE);                   (SAIL)

DECLARATION: EXTERNAL PROCEDURE PICDES(REFERENCE BOOLEAN FAIL;INTEGER
                 ARRAY STORAGE);

        This entry is  for do-it-yourself fans  who want to  read the
file with their own I/O  routine.  STORAGE is filled with  words 7-37
(octal) of  the data  file, which  contain the  pointers to  the data
blocks in the file, as described in the section on FILE FORMAT above.
FAIL is TRUE on exit if there was an error in PICINI.

                     INPUT OF PARTIAL DATA BLOCKS



CALL:        PICLIN(FIRST,NUM,FAIL,STORAGE);         (SAIL)
                          HAND/EYE LIBRARY                        4-9


DECLARATION: EXTERNAL PROCEDURE PICLIN(INTEGER FIRST, NUM; REFERENCE
                 BOOLEAN FAIL; INTEGER ARRAY STORAGE);

        PICLIN  allows  you to  input  specific lines  of  a picture.
FIRST is the first line  number wanted.  Images will be given  to you
starting with that line and continuing for NUM consecutive lines.  If
¬(FLINE≤FIRST≤LLINE)  then  FIRST←FLINE.  if  NUM≤0  then  NUM←0.  If
NUM+FIRST-1>LLINE then NUM←LLINE-FIRST+1.  STORAGE and FAIL  are used
as in PICRD,  except the lengths of  the storage areas  provided need
only  be NUM*LINLEN  words  long and  only  entries 1-4  and  9-12 of
STORAGE are checked for input.

                           MULTI-FILE INPUT


        Occasionally a  user might  wish to  open several  files with
successive calls on PICINI and then selectively read from them.  This
capability is automatically provided  by these routines if  the array
STORAGE, used by all of them, is declared to be at least 51 (decimal)
words long instead  of 25.  Then, for  each file, call PICINI  with a
different 51 word array.   When calling one of the  other procedures,
STORAGE  should  be  the  array  returned  by  PICINI  when  the file
containing the desired picture was opened and the procedure will then
use that file.  Remember to  release all of these file after  you are
done with them.

        When using this feature, PICDES need not be called.   It will
function properly, although slowly, but the 25 words it normally puts
in STORAGE, are already there,  in words 27-51 of the array  for each
file.  Word 26 contains the channel number the file was open on.  The
user must make sure BIT, LINLEN, FLINE, LLINE, RSIDE, and  LSIDE have
the  correct values  if they  are  not the  same for  all  files; the
procedures do not change them after PICINI has given them to you.  Of
the procedures in this file, only PICLIN uses them.

        If you  call one of  the procedures with  a STORAGE  array of
less than 51 words when several files are open, the one last accessed
will be used.

                              STRING I/O


        As explained above, the title and description are strings but
are not in SAIL string format.  To help novice users, below is a SAIL
procedure  to  convert  from  file  strings  to  SAIL  strings.  This
procedure is not in the library; you have to put it in  your program.
A similar procedure to go  from SAIL strings to file strings  is left
as an exercise for the reader.
                          HAND/EYE LIBRARY                       4-10



COMMENT VALUE IS A STRING, GIVEN ARRAY SIZE S AND THE ARRAY B);

STRING PROCEDURE STRCOM(INTEGER S; INTEGER ARRAY B);
        BEGIN STRING FOO, Y;
        INTEGER I,J;
        FOO ← NULL;
        FOR I←1 STEP 1 UNTIL S DO
                BEGIN
                Y ← CVSTR(B[I]);
                FOR J←1 STEP 1 UNTIL 5 DO IF ¬Y[J FOR 1] THEN
                        RETURN(FOO&Y[1 TO J-1]);
                FOO ← FOO&Y;
                END;
        RETURN(FOO);
        END;
                          HAND/EYE LIBRARY                        5-1


                  ENTER - TV BUFFER FETCH AND STORE
                  _____ _ __ ______ _____ ___ _____

FILE:        ENTER
SIZE:        1066
ENTRY:       GRADNT,GVALUE,INTPNT,GENTER,GETPNT,INTPNT
SUBRS:       GLOBAL, TVIN, MISC, SETANG, ENT
INTERNAL:    TNOISE
ACS:         all

        ENTER is a package of subroutines, used by the edge follower,
to randomly  apply a  gradient operator  to the  TV input,  plus fast
store and access of magnitudes.

        The  operator is  the 3  X 3  gradient operator  developed by
Irwin Sobel and Gary Feldman.  If the nine elements of the image are

                A       B       C

                H       I       D

                G       F       E
then the operator is
        vector G = (A-I)[-1, 1] + (B-I)[0,2] + (C-I)[1, 1]

                   + (D-I)[2, 0] + (E-I)[1,1] + (F-I)[0, -2]

                   + (G-I)[-1, 1] + (H-I)[-2,0]
which can be reduced to

                     vector G = X[1, 0] + Y[0,1]


                                 and


                        |G| = SQRT (X↑2 + Y↑2)


                  where X = C + E + 2D - G - A - 2H


                                 and


                     Y = C + A + 2B - G - E - 2F
                          HAND/EYE LIBRARY                        5-2


        This operator computes X and Y and obtains |G| by means  of a
table lookup (maximum  value is 15 (octal)  if BITS is ≥4.   It calls
SETANG to get a number specifying the direction of the gradient.


CALL:        INTPNT;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE INTPNT;

        INTPNT  is an  initialization  routine which  must  be called
before GENTER, GETPNT, or PUTPNT are called.  It must be called again
each time your program changes cells BITS or TVWID in file GLOBAL, or
when DISKIN is called.   It may be called  before or after the  tv is
read the first time.


CALL:        GRADNT;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE GRADNT;

        GRADNT  selects  gradient  output.   The  magnitude   of  the
gradient  vector at  the specified  point and  the  direction number,
explained under SETANG, will be returned.


CALL:        GVALUE;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE GVALUE;

        GVALUE  selects  intensity  output.   The   actual  digitized
intensity  at the  specified  point will  be returned.   This  is the
default option until GRADNT is called.


CALL:        MAG ← GENTER (X, Y, OUTSID, DIR);       (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE GENTER (INTEGER X,Y;
                 REFERENCE BOOLEAN O;REFERENCE INTEGER D);

        GENTER is given  X and Y and  returns values as  specified by
GRADNT and GVALUE.  The density  or magnitude is returned in  MAG and
the vector character (O for the density) in DIR.

        If the  gradient value  to be returned  is less  than TNOISE,
which is assembled as four, MAG will contain zeros on exit.

        If ST indicates tape input and the point requested is outside
                          HAND/EYE LIBRARY                        5-3


the limits in  core, as specified by  the TV control words,  OUTSID ←
TRUE.  If ST indicates TV  input and STVFL indicated that  the buffer
is empty, it is  filled, with unconverted intensities, STV  is marked
unconverted, and STVFL marked full.

        If the point requested is not currently in the buffer, but is
inside the maximum limits of  the TV image, (TMAX, RSMAX,  etc.), the
TV control words would be adjusted to include the point  requested by
calling  one of  the routines  in file  ENT, STVFL  marked  empty and
GENTER  restarted after  calling INTPNT.   The routine  in ENT  to be
called is specified on entry by OUTSID as follows:

     -1  call ENTERY
     0   call ENTERZ (the angle is assumed to be in DIR)

        If the point requested  is outside the maximum limits  of the
TV image, OUTSID ← TRUE.


CALL:        FOO ← GETPNT(X,Y);                      (SAIL)
             PUTPNT(X,Y,VAL);                        (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE GETPNT (INTEGER X,Y);
             EXTERNAL PROCEDURE PUTPNT (INTEGER X,Y,VAL);

        These procedures  very rapidly get  and store  information in
the TV buffer.  To speed  them up, no checking of the  coordinates is
done to make certain they are in the buffer and the area of the image
read in will not  be changed as with  GENTER; the user must  do these
things himself if it is necessary. All parameters relating to  the TV
buffer  are fixed  by the  initialization procedures,  except TVWORD.
Therefore, several buffers of  the same size may be  accessed without
reinitializing before using each one.   If (x,y) is the point,  in TV
cooordinates,  to  be selected,  X  and Y  are  x-LSIDE  and y-FLINE,
respectively, not the coordinates themselves.  This is easy to  do in
FOR loops.  FOO is the  value of the point (X+LSIDE, Y+FLINE)  in the
buffer.  VAL is  the value to  be stored in  the buffer.  It  will be
truncated to the size specified by BITS when INTPNT was last called.
                          HAND/EYE LIBRARY                        5-4


                    ENT - ADJUST LIMITS OF TV SCAN
                    ___ _ ______ ______ __ __ ____

FILE:        ENT
SIZE:        162
ENTRY:       ENTERZ, ENTERY, ENTINT
SUBRS:       GLOBAL
ACS:         1-3,10-11,13


CALL:        ENTERY (Y);                             (SAIL)

DECLARATION: EXTERNAL PROCEDURE ENTERY (INTEGER Y);

        ENTERY sets the TV control words (FLINE, etc) for a rectangle
eleven  points  high  centered  on the  Y  coordinate  given  it, and
stretching the maximum  width of the TV  image as specified  by RSMAX
and LSMAX. STVFL is set to indicate an empty TV buffer.  This routine
is used by the edge follower for calibration and for the  coarse scan
to find edges.   It does not read  the TV image in.   Normally called
from GENTER or OPER.

        ENTINT is an  internal initialization routine used  by GENTER
and OPER .


CALL:        PUSH 17,DIR                             (FAIL)
             PUSHJ 17,ENTERZ
             JRST INSIDE
             JRST OUTSIDE

        Setup  input for  a square  of width  TVWID (assembled  as 65
decimal),  adjusted  so  that  3/4 of  the  square  in  the direction
specified by DIR is in  front of the point (see SETANG  for direction
specification). The routine skips if the point is outside  the limits
set by TMAX, BMAX, LSMAX, RSMAX and SLIM in file GLOBAL is FALSE.  If
SLIM is TRUE then the actual  limits of the TV image are  used.  This
allows a program to restrict a raster scan using the set limits  to a
limited area for  finding a feature, but  going outside that  area if
necessary while processing the feature.

        Below are two examples of the placement of the squares  of TV
input.

                             SEE FIGURE 3
                          HAND/EYE LIBRARY                        6-1


                   HISTO - FORMS HISTOGRAM OF TVBUF
                   _____ _ _____ _________ __ _____

FILE:        HISTO
SIZE:        125
ENTRIES:     HISTO, HISTL, HYSTAB, GHISTO
SUBRS:       GLOBAL
ACS:         1-4, 6-7


CALL:        PUSHJ 17, HISTO                         (MACRO)
             GHISTO (NOTYPE);                        (SAIL)

DECLARATION: EXTERNAL PROCEDURE GHISTO (BOOLEAN T);

        HISTO finds the  number of samples  at each density  level in
the TV buffer and  types them out in  the order 0-17.  On  exit, they
are stored in HYSTAB to  HYSTAB +17.  The routine halts if  BITS does
not contain 4.

        When called with  HISTO, the histogram  will be typed  out if
HISTL contains a SKIPA, as it does when loaded.  If HISTL  is changed
to a SKIP, the subroutine will exit without typing.

        GHISTO is the SAIL entry.  If NOTYPE is TRUE there will be no
typeout.  If it is FALSE, the histogram will be typed.
                          HAND/EYE LIBRARY                        6-2


                      OPER - HUECKEL'S OPERATOR
                      ____ _ _________ ________

FILE:        OPER
SIZE:        2406
INTERNAL:    ORX, ORY, OCL, OSL, OD, OB (all type REAL)
ENTRY:       OPER, OPINIT
SUBRS:       GLOBAL, ENT, TVIN, MISC
ACS:         0-4

        This program applies a variable sized operator,  developed by
Manfred Hueckel, to  TV images to detect  edges.  While the  speed of
the operators is less than  than of the other operators  described in
this document, they provide  a more complete description of  the edge
and can find edges when excessive noise and lack of  contrast prevent
the other operators from finding the edges.  For a description of the
math behind these operators  see Manfred's paper, "An  Operator Which
Locates Edges in Digitized Pictures".  (AI Memo - 105)


CALL:        OPINIT (C)                              (SAIL)

DECLARATION: EXTERNAL PROCEDURE OPINIT (INTEGER CIRCLE};

        OPINIT initializes the operator for a specified TV  image and
operator size.   It must  be called whenever  the size,  position, or
sample width of the image  changes; the TV buffer is changed;  or the
operator size is changed. CIRCLE is an integer in the range

                            0 < CIRCLE ≤5

indicating  the  operator  size  to  be  used.   The  five  tables of
constants for the operators take up 11000 (octal) words.  The program
can be assembled without the larger operators if they are not needed,
greatly reducing the size of the program. The current version  in the
library  is assembled  with only  the first  two tables.  OPINIT will
return  immediately  if given  any  sizes  other than  1  or  2.  The
operator sizes are as follows:

     CIRCLE   RADIUS*     RANGE**      # OF POINTS USED (octal)
     ______   _______     _______      _ __ ______ ____ _______
                          - +
     1        3.19        3 4          32
     2        4.07        4 5          52
     3        4.67        5 5          69
     4        6.60        7 7          137
     5        7.51        8 8          177
                          HAND/EYE LIBRARY                        6-3


     *        Radius of  the circle approximated  by the  operator in
              points of the TV image.

     **       Extent  of the  operator  in points.  Also  the minimum
              distance from  the edge  of the TV  image at  which the
              operator  will not  extend  outside the  limits  of the
              image. +  and -  refer to the  direction along  the two
              axes.  Therefore, for the operator #1 to be  inside the
              image at point X, Y

                      LSIDE + 3 ≤ X ≤ RSIDE - 4
                      FLINE + 3 ≤ Y ≤ LLINE - 4

        Note that circles  1 and 2 have  a diameter which is  an even
number of resolution  elements.  When these circles  are approximated
by a grid, there  are an even number  of grid points along  both axes
through the operator,  causing the center to  lie outside the  set of
points at  which the  intensities are sampled.   The center  of these
operators are actually at (X+.5, Y+.5), causing a slight shift in the
positive X and Y directions which can be noted in the table above.


CALL:        COH ← OPER (X,Y,ANGLE,FLAG);            (SAIL)

DECLARATION: REAL PROCEDURE OPER(INTEGER X,Y,ANGLE,FLAG);

        OPER  applies  the operator  specified  by OPINIT  to  the TV
image.   The center  is  at (X,Y).   It returns  seven  numbers which
specify an edge,  if one is found,  and give noise  information.  The
edge is specified as follows:

                             SEE FIGURE 6


        If an edge exists in the area covered by the operator:

     ORX,ORY   is the intersection of the edge with a  vector through
               (X,Y) normal to the edge.  Thus (ORX,ORY)  will always
               be a point on the edge inside the area covered  by the
               operator.  The closer  (ORX,ORY) is to (X,Y)  the more
               accurate its  value.  It will  usually be  accurate to
               within 1.5 points anywhere inside the operator.

     OCL,OSL   specifies  the  vector  normal  to  the  edge  through
               ORX,ORY.  It is a unit vector (i.e. OCL↑2 +OSL↑2  = 1)
               and  it always  points  toward the  lighter  side (the
               higher  intensity values).   Therefore, it  is  in the
                          HAND/EYE LIBRARY                        6-4


               direction of the gradient. Again, its  accuracy varies
               in a way that is similar to ORX,ORY.

     OB        The average intensity on the darker side of the edge.

     OD        The difference between the intensities on  either side
               of the  edge. It  will always  be positive  unless the
               average  intensity is  very close  to zero  (<.05), in
               which case it may go negative a small fraction (<.03).
               OB and OD can  become very inaccurate if  the distance
               between  (X,Y)  and (ORX,ORY)  increases.   Wide edges
               make the values much less accurate than noisy ones.

        If there is no edge, the operator will attempt to  divide the
circle so that the noise distribution gives the largest value  of OD,
which should be quite small.  OCL and OSL will take on  random values
and OB will be the average  intensity in the area.  ORX and  ORY will
take on  values which are  often equal to  X and Y  or very  close to
them.  Sometimes, however, ORX and ORY take values much  further from
X,Y than the radius of the operator.

        The seventh number, COH, which is the value of  the operator,
is an indicator of the quality of the edge.  If COH > .98 there is an
edge; if COH < .9 there is not  an edge.  For .9 ≤ COH ≤ .98  an edge
may be present.  Since the  goodness of the edge depends both  on COH
and OD (if OD  is less than the noise  level, you can still  get good
values for COH), Manfred suggests accepting an edge if

             COH + (1 - CONF) x OD↑2 / (DIFF↑2 + OD↑2) >1

where CONF  relates to  COH and  DIFF relates  to OD.   The suggested
ranges are

                           .86 < CONF <.9
                           1.5 < DIFF < 4

        0 ≤ COH  ≤ 1.0 except (1)  when the operator  extends outside
the limits of the TV image, in which case COH = -1.0 and, (2)  if the
operator routines become confused, in which case they terminate early
without setting any  of the variables  listed aboue and  COH=-2.0. If
the operator is inside the TV limits but outside the  current buffer,
a new buffer will be read  in, using the routines in file  ENT.  FLAG
indicates what shape the input area should assume as follows:

     -1  ENTERY
     0   ENTERZ (ANGLE gives the direction)
                          HAND/EYE LIBRARY                        6-5


        FLAG≠0 only if the operator size is 1-3.  The other operators
are wider than the area read in.

        I have experimented running operators of all sizes over edges
of various types, including some so noisy and faint that the gradient
operator probably could not see them.  I propose the following method
of edge detection, which will usually be much faster and, apparently,
more accurate, than the equation given above.

        1.  If COH < .85  or OD < N there  is no edge.  If COH  > .98
and OD > M there  is an edge.  N and  M can be chosen to  reflect the
intensity change expected for the  scene being analyzed.  I used  N =
1, which is  the lowest reasonable  value.  I used M  = 2 but  if you
have an idea of what the intensity change should be, this can  be set
just below that.

        2. For other values, an edge may be present.  One  test which
can be applied here is to reject the edge if

                    (ORX - X)↑2 + (ORY -Y)↑2 ≥ R↑2

where R is the radius of operator in use.

        3.  If great accuracy is not necessary, all edges accepted in
Step 1 can be finished  with now.  My experience has  shown, however,
that,  while the  location  of the  edge is  found  fairly accurately
anywhere inside the  area covered by the  operator, OB and OD  can be
quite unreliable if  (X,Y) is not near  (ORX, ORY).  If  the distance
between them is nearly equal to the radius of the operator,  the edge
may  be found  very accurately,  but OB  and OD  may blow  up, giving
values well outside  of the expected  range (like OB  = 499 and  OD =
813).  In this case the subroutine returns after setting COH=-2.0 and
OB and OD = 0.

        Therefore, for edges which got a maybe rating in test  1, and
sure edges where accuracy is important and (ORX -X)↑2 + (ORY - Y)↑2 >
(R/2)↑2, the  operator should be  applied again, letting  (X,Y) equal
(ORX, ORY) rounded to the nearest integer.  Then apply tests 1  and 2
again. If they fail, there is  no edge.  If they give a  maybe rating
and  OD and  COH are  lower than  or equal  to their  previous value,
reject the edge.   Otherwise apply test  3 again and  continue.  This
process should converge,  usually in two  or less iterations,  if the
right side of the last  equation above is not less than  (R/2)↑2.  If
the points are closer it may oscillate.
                          HAND/EYE LIBRARY                        6-6


                    AVERAG - AVERAGING SUBROUTINE
                    ______ _ _________ __________

FILE:        AVERAG
SIZE:        264
INTERNAL:    NUMBR, TMPBUF
SUBRS:       TVIN, MISC, GLOBAL
ACS:         ALL


CALL:        AVERAG;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE AVERAG;

        AVERAG forms the average over several frames of the specified
area of the TV  input.  On entry the  TV control words should  be set
for TVIN and BITS should contain the sample width of the average.  It
may be any value from 3 through 6.  NUMBR should contain 4, 8,  or 16
to give an average  over 4, 8, or  16 frames.  Any other  number will
give an  8 frame average.   The first image  read is unpacked  into a
temporary buffer in 8 bit bytes and the remainder of the images added
to it.  Then the sums are truncated to the requested number  of bits,
with  rounding, and  put back  in the  TV buffer.   ADJUST  is called
before returning.

        A temporary buffer  must be specified  by putting an  IOWD in
TMPBUF.  If it is not at least twice the length of the TV  buffer the
routine will exit immediately.
                          HAND/EYE LIBRARY                        6-7


     DIFR - ROUTINES FOR DIFFERENCING IMAGES AND PROCESSING THEM
     ____ _ ________ ___ ____________ ______ ___ __________ ____

FILE         DIFR
SIZE:        771
ENTRIES:     DIFER, SUPRES, PRNT, HISTOG
SUBRS:       GLOBAL
ACS:         ALL

        This is a package of procedures for processing differenced TV
images.  They  are in FAIL  and are optimized  for speed.   They work
fastest when the images  were essentially identical except  for noise
(for motion detecting, etc.).


CALL:        DIFER(BUF1, BUF2, THRESH);              (SAIL)

             PUSH 17,BUF1
             PUSH 17,BUF2
             PUSH 17,THRESH
             PUSHJ 17,DIFER                          (FAIL)

DECLARATION: EXTERNAL PROCEDURE DIFER(INTEGER BUF1, BUF2, THRESH);

        This procedure differences two four bit TV images, which must
be of  the same size  (no checking is  done).  The current  values of
FLINE,  LLINE, etc.,  are used  to determine  the dimensions  of both
images.   BUF1 and  BUF2 are  IOWDs (from  GIOWD or  CORGET  in SAIL)
specifying the two buffers.  BUF1 is replaced by the magnitude of the
differences at  each point  of the image.  All differences  less than
THRESH will be set to zero.  THRESH is forced ≥2 by the program.


CALL:        SUPRES(BUFIN, BUFOUT, THRESH);          (SAIL)

             PUSH 17,BUFIN
PUSH 17,BUFOUT
             PUSH 17,THRESH
             PUSHJ 17,SUPRES                         (FAIL)

DECLARATION: EXTERNAL PROCEDURE SUPRES(INTEGER BUFIN,BUFOUT,THRESH);

        This routine applies a  noise suppression operator to  the TV
image in BUFIN and puts  the result in BUFOUT, where the  buffers are
specified by IOWDs as for DIFER.  The TV control words must be set up
for BUFIN.  The  program will change them  for BUFOUT, which  has two
fewer rows and columns.
                          HAND/EYE LIBRARY                        6-8


        A  point  in BUFOUT  is  zero if  the  number  of intensities
greater  than  zero  amoung  the  eight  neighboring  points  of  the
corresponding  point in  BUFIN is  less than  THRESH.   Otherwise the
point has the same value in both buffers.


CALL:        PRNT(BUFR);                             (SAIL)

             PUSH 17,BUFR
             PUSHJ 17,PRNT                           (FAIL)

DECLARATION: EXTERNAL PROCEDURE PRNT(INTEGER BUFR);

        This routine outputs the TV image specified by the  IOWD BUFR
to  the line  printer, using  channel 16.   It is  similar  to PRDUMP
except no table or coordinate numbers are printed.  A row  of periods
is printed across the top and bottom of each strip to show how far it
extends in each dimension.  The numbers 1-7 and letters A-H  are used
to  denote  intensities  1-15 (only  4  bit  samples  allowed), while
intensity zero prints  as a blank.  This  last feature, and  a slight
increase  in  speed, make  it  preferable to  PRDUMP  for differenced
images.


CALL:        HISTOG(BUFR,OUT);                       (SAIL)

             PUSH 17,BUFR
             PUSH 17,[OUT]
             PUSHJ 17,HISTOG                         (FAIL)

DECLARATION: EXTERNAL PROCEDURE HISTOG(INTEGER BUFR; ANY ARRAY OUT);

        This procedure generates the histogram of the 4 bit  TV image
specified by the IOWD  BUFR and the TV  control words and puts  it in
the first sixteen  words of array OUT,  which has better be  at least
that long.  It is similar  to HISTO but much faster for  images which
are mainly zeros.
                          HAND/EYE LIBRARY                        6-9


                   DISP - DISPLAY DIFFERENCED IMAGE
                   ____ _ _______ ___________ _____

FILE:        DISP
ENTRY:       DISPLY
SIZE:        202
SUBRS:       MISC,  QUAM  DISPLAY  ROUTINES,  GLOBAL,   SAIL  RUNTIME
             ROUTINES
ACS:         ALL


CALL:        DISPLY(BUFR,DISBUF,THRESH,DISLEN,FRAME);(SAIL)

DECLARATION: EXTERNAL PROCEDURE DISPLY(INTEGER BUFR;
                 ANY ARRAY DISBUF;INTEGER THRESH, DISLEN,FRAME);

        This procedure generates a fast (and crude) display of the TV
buffer specified  by the  IOWD BUFR  and the  TV control  words.  The
buffer should contain a  differenced image which is mainly  zeros, or
else the display buffer will have to be very large.  A dot is  put on
the display for each nonzero point in the buffer with value ≥ THRESH,
which is  forced by  the program to  be one  or greater.   If several
adjacent point in the same row are nonzero, a horizontal line will be
drawn through them.  DISBUF is an array for use as the display buffer
which is at  least of length DISLEN+2.   FRAME is the piece  of glass
number to be used.  Some version of the QUAM display routines must be
loaded with this file.
                          HAND/EYE LIBRARY                       6-10


                      HUECKEL EDGE-LINE OPERATOR
                      _______ _________ ________

FILE:        OP
SIZE:        3200
ENTRIES:     EJLI,EJINIT
EXTERNAL:    CONF, DIFF
INTERNAL:    B, TM, TP,  N0SQ, S0SQ, COH,  CX, CY, OPX,  OPY, ISEDGE,
             ISLINE,  BCOMP,  WEAK,  NOISY,  NEARED,  OPOOB,  CIRCLE,
             LINWID, OPXM, OPYM, OPXP, OPYP, OPOOB
CALLS:       GLOBAL, SAIL runtime routines, ENT
ACS:         ALL


CALL:        EJINIT(SIZE);                           (SAIL)

             PUSH 17,SIZE
             PUSHJ 17,EJINIT                         (FAIL)

DECLARATION: EXTERNAL PROCEDURE EJINIT(INTEGER SIZE);

        This  procedure  initializes  the  data  structure   for  the
operator.  SIZE is the operator  number (1 and 2 are legal,  the rest
are ignored).  See description of OPER for discussion of  the various
operator sizes.  EJINIT must be call before the first  application of
the operator and,  thereafter, whenever TVWORD, FLINE,  LLINE, RSIDE,
LSIDE  or  BITS are  changed,  or whenever  a  different  operator is
desired.


CALL:        FOUND←EJLI(X,Y,ANGLE,FLAG);             (SAIL)
             PUSH 17,X
             PUSH 17,Y
             PUSH 17,ANGLE
             PUSH 17,FLAG
             PUSHJ 17,EJLI
             JUMPN 1,FOUND                           (FAIL)

DECLARATION: EXTERNAL BOOLEAN PROCEDURE EJLI(INTEGER X,Y,ANGLE,FLAG);

        This procedure applies the  operator at the pont (X,Y)  in TV
coordinates.  The value of the operator is TRUE if there was anything
at  all in  the disc.   One must  set the  decision  variables before
calling.  CONF  should  be  set  to  the  desired  confidence.  It is
recommended that  .85<CONF<.99.  DIFF  should be  set to  the minimum
signal strength allowable.   Both DIFF and  CONF must be  declared in
your program as INTERNAL REAL and initialized by your  program before
using.  The signal strength is returned in S0SQ and is the sum of the
                          HAND/EYE LIBRARY                       6-11


squares of the components of the fourier expansion.  There is a vague
relatin between  the signal  strength and the  square of  the minimum
brightness step size.   The recommended range is  2.0<DIFF<10.0.  The
actual confidence is returned  in COH and is  S0SQ/(S0SQ+N0SQ).  N0SQ
is a measure of the amount  of signal that is not an  ideal edge-line
element.

        The boolean WEAK will be TRUE if the operator  failed because
there was  very little  action in the  disc.  NOISY  will be  TRUE if
there was plenty of  action, but it did  not look much like  an ideal
edge-line element.  OPOOB will be  TRUE if X,Y was outside  the field
of view of the TV or the operator was prevented from moving its input
rectangle.  FLAG and ANGLE are used to move the rectangle,  using the
mechanism described under OPER.

        The disc  is partitioned upon  success into three  regions of
brightness, B, B+TM, and B+TM+TP, respectively.  It is partitioned by
two straight lines whose equations are  CX*X+CY*Y=CX*OPXM+CY*OPYM and
CX*X+CY*Y=CX*OPXP+CY*OPYP respectively.  CX and CY are  the direction
cosines  of  the  line  and  (OPXM,OPYM)  and  (OPXP,OPYP)   are  the
coordinates of the closest points  on the lines to the center  of the
operator.

        There is a variable, R,  that is the weighted average  of the
distances to each of the lines.  If the disc is placed over  an ideal
edge element, R will be the  distance from the center of the  disc to
the center of the edge  OPX,OPY are the coordinates of the  center of
the  edge-line  element.  The  boolean  ISLINE will  be  TRUE  if the
element looks more like a line than an edge, and ISEDGE will  be TRUE
if it looks  more like an  edge than a  line.  Ofter neither  will be
TRUE.  The boolean NEARED will  be TRUE if the edge-line  element was
too close to the edge of the disc to be confident of the position and
brightness information.

        BCOMP is TRUE if  the internal computation went  complex.  In
this case,  the brightness is  set to the  average brightness  of the
picture  inside the  disc, but  R, OPX,  OPY, CX,,  and CY  are still
meaningful.  In this case, the data in the disc was too  confusing to
have a meaningful  fit as an ideal  edge-line element, but  often the
operator can  be moved either  to (OPX,OPY) or  down the line  in the
direction  specified by  CX  and CY  are will  then  yield meaningful
results.

        If the element in the  disc is definitely a line,  the number
LINWID is  returned as the  width of the  line.  It is  equivalent to
SQRT((OPXP-OPXM)↑2+(OPYP-OPYM)↑2).
                          HAND/EYE LIBRARY                       6-12


        The disc radius in  floating point is in CIRCLE  after EJINIT
has been called.

        In using  the operator, remember  that many things  look like
lines.   For instance,  two parallel  nearby edges  may very  well be
called a line.
                          HAND/EYE LIBRARY                        7-1


                 PICWR - WRITE A PICTURE ON THE DISK
                 _____ _ _____ _ _______ __ ___ ____

FILE         PICWR
SIZE:        151::
SUBRS:       SAIL RUNTIME ROUTINES, GLOBAL
ACS:         ALL


CALL:        PICWR(CHAN,FILE,EXT,PPN,FAIL,STORAGE)   (SAIL)

DECLARATION: EXTERNAL PROCEDURE PICWR(INTEGER CHAN, FILE, EXT, PPN;
                 REFERENCE BOOLEAN FAIL; INTEGER ARRAY STORAGE);

        This procedure writes out a picture onto a disk file,  in the
new picture format  (see PICRD for a  description of the  file format
and the storage array).  CHAN is the channel number for  output.  The
picture is  put on file  FILE.EXT[PPN], where the  parts of  the file
descriptor are sixbit words as produced by CVFIL.  STORAGE is  the 25
word  array specifying  the data  blocks to  be written.   Each entry
contains  zero, if  that data  block does  not exist,  or  XWD -<word
count>, <address of first word of array or block of core containing a
data block>. This is an IOWD+1.  FAIL is TRUE on exit if there was an
error of any kind, in which case the picture was not written out.

        Currently the entire file is written in one call.   If people
would like to be able to open the file and then fill it using several
calls,  to  reuse  the  arrays and  save  space,  this  feature could
probably be implemented.
                          HAND/EYE LIBRARY                        7-2


                  PRDUMP - PRINTER OUTPUT SUBROUTINE
                  ______ _ _______ ______ __________

FILE:        PRDUMP
ENTRIES:     PRDUMP, PRPIC
SIZE:        1137
SUBRS:       GLOBAL
ACS:         1-7, 16


CALL:        PRDUMP;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE PRDUMP;

        PRDUMP  outputs  the  TV  buffer  on  the  line  printer, one
character per sample.  The coordinates are printed across the top and
bottom and down  the left side of  the output.  The column  under the
first digit of  the x-coordinate corresponds  to the number.   If the
width of the image is over 160 (octal) points, the first  160 columns
are printed in  a block, followed by  more blocks of 160  columns, or
fractions thereof) ,  until the entire  image has been  printed.  The
output starts at  the top of a  page and page boundaries  are ignored
thereafter.

        The densities are considered to be SIXBIT characters  and are
converted to ASCII for output, with a conversion table  printed after
the buffer.   PRDUMP initializes the  line printer and  releases both
the printer and its buffers before returning.


CALL:        PRPIC;                                  (SAIL)

DECLARATION: EXTERNAL PROCEDURE PRPIC;

        This subroutine is similar  to PRDUMP except it  expects four
bit samples and it does  overprinting on the line printer  to produce
output with eight density levels so it will resemble the  input image
when viewed from a distance.  If BITS≠4 then the high order four bits
will be used.
                          HAND/EYE LIBRARY                        7-3


                       PORTR - PORTRAIT PRINTER
                       _____ _ ________ _______

FILE:        PORTR
SIZE:        122
INTERNAL:    PRTBUF
SUBRS:       GLOBAL, PRDUMP
ACS:         1-7, 16


CALL:        PORTR;                                  (SAIL)

DECLARATION: EXTERNAL PROCEDURE PORTR;

        This is  IRWIN SOBEL'S  portrait program.   Given a  four bit
image specified by  TVWORD, it creates a  new image, specified  by an
IOWD which the user must put in PRTBUF before calling, which  has its
lines  adjusted so  the  distance between  them  is the  same  as the
distance between  columns.  PRPIC  is then called  to print  an image
which is not stretched on the output.  PORTR will exit immediately if
BITS ≠ 4.  The array specified  by PRTBUF should be the same  size as
the one specified by TVWORD. It may be the same array if the original
image is not needed any more.
                          HAND/EYE LIBRARY                        7-4


                VIDEO - TV IMAGE TO VIDEO SYNTHESIZER
                _____ _ __ _____ __ _____ ___________

FILE:        VIDEO
SIZE:        SAIL PROCEDURE
SUBRS:       GLOBAL, SAIL RUNTIME ROUTINES
ACS:         ALL


CALL:        OK ← VIDEO(EXP,X,Y);                    (SAIL)

DECLARATION: EXTERNAL BOOLEAN PROCEDURE VIDEO(INTEGER EXP,X,Y);

        The  TV image  specified by  TVWORD is  sent to  Quam's DDVID
program for display on  Data Disk channel 47.   DDVID.DMP[1,PDQ] must
be running as a seperate job.  EXP is a small integer  specifying the
power of two by which the picture should be blown up  for displaying.
The smallest picture  (EXP=1) is twice normal  size. X and  Y specify
the  coordinates  of  the  upper  left  corner  of  the  image  in TV
coordinates (upper left corner of screen is 0,0).

        If only one  copy of DDVID is  running, it will be  used.  If
there are several copies of DDVID but only one running under the same
PPN as the calling job, that copy will be used.  In all  other cases,
an error message will be typed.  If an error is detected, or DDVID is
not accepting pictures, the procedure returns FALSE; otherwise  it is
TRUE.  The  procedure does not  wait for DDVID  to put out  the image
before returning.
                          HAND/EYE LIBRARY                        8-1


                      MISCELLANEOUS SUBROUTINES
                      _____________ ___________

FILE:        MISC
SIZE:        144
SUBRS:       GLOBAL
ENTRIES:     GXCT,  LABEL,  GIOWD,  BUTTON,  ADJUST,  SPWON,  SPWOFF,
             ADCHG, RDCHG, FADCHG, FRDCHG
ACS:         1-3, 16

        This   file   contains   various   small,   frequently   used
subroutines.


CALL:        ADJUST;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE ADJUST;

        ADJUST uses BITS to change TVOUT and LINLEN.  This subroutine
must be called by any  routine written by the user which  changes the
number of  bits per sample  in the TV  buffer or the  output routines
will not work properly.


CALL:        PUSHJ 17, BUTTON                        (MACRO)
             FOO ← BUTTON;                           (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE BUTTON;

        BUTTON - In many programs it is desired to move the rectangle
around the TV picture.  For this and other applications there exist a
set of  eight buttons  (known as SPACEWAR  buttons for  reasons which
shall not be divulged here) in two boxes near the TV Camera.   If any
of  the buttons  are depressed  when this  subroutine is  called, the
appropriate bit in accumulator 1 is one when the routine  exits.  The
buttons are read into the right  eight bits of the word as  marked on
the side of the buttons; the remainder of the word is cleared.

        The following  subroutines are for  use with  SAIL procedures
only:


CALL:        FOO ← GIOWD (A);                        (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE GIOWD (ANY ARRAY A);

        A is  a one-dimensional  SAIL array  identifier.  An  IOWD is
returned in FOO specifying the start and length of the array.
                          HAND/EYE LIBRARY                        8-2




CALL:        FOO ← GLABEL ← GLABEL(VAR);             (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE GLABEL (REFERENCE ANY V);

        The address of VAR is returned in FOO.


CALL:        FOO ← GXCT (INST,ARGL);                 (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE GXCT (ANY I,A);

        ARG is placed in AC1 and INST is executed.  FOO is the result
in AC1.


CALL:        SPWOFF;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE SPWOFF;

        Turns off spacewar mode.


CALL:        SPWON(TICK,ADDR);                       (SAIL)

DECLARATION: EXTERNAL PROCEDURE SPWON(INTEGER TICK;
                 REFERENCE INTEGER ADDR);

        Turns on spacewar mode by executing SPCWAR TICK,ADDR.


CALL:        ADCHG(X,Y,PROC);                        (SAIL)

             PUSH 17,X
             PUSH 17,Y
             PUSH 17,[PROC]
             PUSHJ 17,ADCHG                          (FAIL)

DECLARATION: EXTERNAL PROCEDURE ADCHG(INTEGER X,Y;PROCEDURE PROC);

        X and  Y are  assumed to be  absolute TV  coordinates.  ADCHG
converts them to III  display coordinates and transfers  to procedure
PROC, which is normally AVECT, AIVECT, or APOINT in the  Quam display
package.  Any other  procedure can be used  which expects X and  Y as
its last two arguments.  ADCHG converts them in the stack and flushed
the procedure address.  Then  it JRSTs to the procedure,  leaving the
return on the stack.
                          HAND/EYE LIBRARY                        8-3




CALL:        RDCHG(X,Y,PROC);                        (SAIL)

        RDCHG is  identical to  ADCHG except  it expects  relative TV
coordinates and normally calls RIVECT, RVECT, or RPOINT.

        There  also  exist  routines  FADCHG  and  FRDCHG  which  are
identical in use to ADCHG and RDCHG except they take X and Y are REAL
variables.  There produce much more accurate displays if X and  Y can
take real values.

        The following subroutines are for internal use only:


LOCKON

LOCKOF
                          HAND/EYE LIBRARY                        8-4


                     LOOKUP - SYMBOL TABLE SEARCH
                     ______ _ ______ _____ ______

FILE:        LOOKUP
SIZE:        24
ACS:         1-3, 16


CALL:        PUSHJ 17, LOOKP                         (MACRO)

        LOOKP is called with the  RADIX50 code for a symbol  in AC16.
It will skip one instruction  when it returns if the symbol  given to
it exists  in the symbol  table as a  global and leaves  the symbol's
value in AC16.
                          HAND/EYE LIBRARY                        8-5


                      POT - POT READING ROUTINE
                      ___ _ ___ _______ _______

FILE:        POT
SIZE:        145
ENTRIES:     POTABS, POTREL
INTERNAL:    POTS
ACS:         1-10


CALL:        VAL ← POTABS (CHAN, FLAG);              (SAIL)
             VAL ← POTREL (CHAN, FLAG);

DECLARATION: EXTERNAL INTEGER PROCEDURE POTABS (INTEGER CHAN;
                 REFERENCE INTEGER FLAG);
             EXTERNAL INTEGER PROCEDURE POTREL (INTEGER CHAN;
                 REFERENCE INTEGER FLAG);

        POTABS and POTREL read the pots attached to A-D  channels 12-
15.  CHAN is a  number in the range 1  thru 4 to indicate the  pot on
channel  12  through 15  and  the  pot reading  for  that  channel is
returned.  Cells  POTS and POTS  + 1 contain  all four  raw readings,
twelve bits per channel.  If CHAN is zero, the value of the procedure
for all four channels  is put in cells POTS  through POTS + 3  and no
value returned.

        POTABS gives the absolute  pot reading, which will be  in the
range -2048  to about 2044  (decimal).  Be warned  that the  pots are
noisy in the last two bits, are not linear, and not repeatable.

        POTREL gives the pot reading relative to the last reading for
that channel.   If FLAG  is ≠0 on  entry, the  last reading  for that
channel, or all four if CHAN = 0, will be set to the current reading.
Zero will be the value of the procedure in this case.

        On exit, FLAG is set as follows:

     FLAG   MEANS
     ____   _____
     0      OK
     1      Illegal channel number (<0 or >4)
     -1     Could not initialize A-D on 1000 consecutive tries.
     -2     Data missed from 136 on 1000 consecutive tries.

HINT FOR POT USERS     [Don't get caught!]

        Some library  routines using the  pots read them  in relative
mode  and scale  the  result so  that a  complete  turn of  a  pot is
slightly more  than the  range of the  variable being  changed.  This
                          HAND/EYE LIBRARY                        8-6


means that it is possible, in fact easy, to get the pot in a position
where turning it to its stop in the proper direction does  not change
the variable  as far in  that direction as  you want.  In  this case,
rotate the pot  as far as  it will go the  other way.  This  puts the
variable at one of its limits and then if you move the pot  the other
way, you have the entire range at your disposal.
                          HAND/EYE LIBRARY                        8-7


                 GLBGET - READ GLOBAL DATA STRUCTURE
                 ______ _ ____ ______ ____ _________



FILE:        GLBGET
SIZE:        SAIL PROGRAM
INTERNAL:    REQUIREs PREAMB.SAI
ACS: ALL


CALL:        BLOBS←GLBGET;                           (SAIL)

DECLARATION: EXTERNAL SET PROCEDURE GLBGET;

        This procedure reads in the global data  structure proceduced
by the curve fitter from disk files.  See EDGCUR.LST[SYS,HE]  for the
edge  follower  commands  which  dump  the  data  structure  and  for
descriptions of the data structure and the file format.

        The program requests a file name and then reads in  the file,
regenerating the data  structure in the  global model.  It  then asks
for another file  name.  As many files  as desired may be  entered at
once.  A new object  item is created for  each object in each  of the
files.  When input is terminated by giving the procedure a  null file
name, it returns the object items as a set.
                          HAND/EYE LIBRARY                        8-8


       INTERP - INTERRUPT ROUTINE (as used by hand/eye system)
       ______ _ _________ _______ ___ ____ __ ________ _______

FILE:        INTERP
SIZE:        60
ENTRIES:     INTINT, INTWAIT
INTERNAL:    DISABLE
ACS:         1

        INTERP allows  SAIL programs  to use the  TTY, PTY,  and MAIL
interrupts in the system.


CALL:        INTINT(TTY,PTY,MAIL);                   (SAIL)

DECLARATION: EXTERNAL PROCEDURE INTINT(BOOLEAN TTY,PTY,MAIL);

        This  routine initializes  the interrupts  and masks  them so
they  will not  break.  All  interrupts pending  are  lost.  Previous
interrupt  addresses, if  any,  in JOBAPR  are  destroyed.  Arguments
which are TRUE enable interrupts as follows:

          TTY      teletype input

          PTY      pseudo-teletype input

          MAIL     mail waiting

        If DISABL,  assembled as  FALSE, is set  TRUE when  INTINT is
called, the interrupt feature is disabled and INTWAIT will sleep four
ticks and return whenever called.  This is mainly for debugging.


CALL:        INTWAIT;                                (SAIL)

DECLARATION: EXTERNAL PROCEDURE INTWAIT;

        When INTWAIT  is called, the  interrupts requested  by INTINT
are  unmasked  and  the  program  goes  into  interrupt   wait.   Any
interrupts which  are pending (the  condition occured since  the last
call of INTWAIT or INTINT but was masked out) will cause an immediate
interrupt.  Whenever  an interrupt occurs  it will be  dismissed, the
masks  will be  set again,  and the  procedure returns.   The calling
program must  then check  to determine  what condition(s)  caused the
interrupt by interrogating the system or checking JOBCNI.

        The error message "INTERRUPT ROUTINE CONFUSED" means:
                          HAND/EYE LIBRARY                        8-9


1.  You  just did  ↑C  and S  to  restart your  program.   Ignore the
    message.

2.  You tried to continue your  program from DDT when it has  been in
    interrupt wait.  You should have started it at INTWAIT or  it may
    even be fatal.

3.  The timesharing system  has interrupted but no  condition enabled
    for is present.  Shoot a systems programmer.

4.  You tried to  run another program  which the current  program was
    waiting for an interrupt.  You will win if you try it again.
                          HAND/EYE LIBRARY                       8-10


                    TELL - WHO HAS YOUR I/O DEVICE
                    ____ _ ___ ___ ____ ___ ______

FILE:        TELL
SIZE:        101
ACS:         1-7


CALL:        TELL(DEVICE);                           (SAIL)

             PUSH 17,DEVICE
             PUSHJ 17,TELL                           (MACRO)

DECLARATION: EXTERNAL PROCEDURE TELL(INTEGER DEVICE);

        DEVICE  is  the  name  of  an  I/O  device  in  SIXBIT.  This
procedure will type out a message of the form

                  device INITED BY JOB n, PPN= x,xxx

where 'device' is the  device name you gave  it.  If there is  no job
number or PPN, the device was not initialized or assigned at the time
the procedure checked the system's device tables.
                          HAND/EYE LIBRARY                       8-11


                      SETANG - ANGLE CONVERSION
                      ______ _ _____ __________

FILE:        SETANG
SIZE:        206
ACS:         1, 2, 12, 13


CALL:        ANGLE ← SETANG(DX, DY);                 (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE SETANG(INTEGER DX, DY);

        DX and DY  are the (signed) X  and Y components of  a vector.
SETANG returns  the angle number  for that vector,  used in  OPER and
ENTER. |DX| and |DY| must be less than 16.  The number is interpreted
as follows (TV coordinates):
                4
            5      3
        6       o       2   X→
            7      1
                0

                Y
                ↓